青岛理工大学第五届ACM交流赛 部分题解

A:后缀维护si*pi的最小值,查询的时候二分,判断后缀和当前两个部分就行。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 typedef long long LL;
 5 const int maxn = 100100;
 6 int n, m;
 7 LL s[maxn], p[maxn];
 8 LL suf[maxn];
 9
10 int main() {
11     // freopen("in", "r", stdin);
12     int T;
13     LL q;
14     scanf("%d", &T);
15     while(T--) {
16         scanf("%d%d",&n,&m);
17         memset(suf, 0, sizeof(suf));
18         for(int i = 0; i < n; i++) scanf("%lld%lld",&s[i],&p[i]);
19         suf[n-1] = s[n-1] * p[n-1];
20         for(int i = n - 2; i >= 0; i--) suf[i] = min(suf[i+1], s[i]*p[i]);
21         s[n] = 100000000000000LL; suf[n] = 100000000000000LL;
22         while(m--) {
23             scanf("%lld", &q);
24             int pos = lower_bound(s, s+n+1, q) - s;
25             // if(s[pos] == q) printf("%lld\n", q*p[pos]);
26             if(pos == n) printf("%lld\n", q*p[n-1]);
27             else printf("%lld\n", min(suf[pos], q*p[pos-1]));
28         }
29     }
30     return 0;
31 }

B:先离散化找出所有内容的种类,之后尺取卡出最小页数。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 const int maxn = 1001000;
 5 int n, m, rl, rr;
 6 int h[maxn], p[maxn];
 7 int vis[maxn];
 8 int cnt, ret;
 9
10 int id(int x) {
11     return lower_bound(h, h+m, x) - h;
12 }
13
14 int main() {
15     // freopen("in", "r", stdin);
16     while(~scanf("%d", &n)) {
17         for(int i = 0; i < n; i++) {
18             scanf("%d", &p[i]);
19             h[i] = p[i];
20         }
21         sort(h,  h+n); m = unique(h, h+n) - h;
22         memset(vis, 0, sizeof(vis));
23         cnt = 0; ret = n; rl = 0, rr = n - 1;
24         int lo = 0, hi = 0;
25         while(lo < n) {
26             while(hi < n && cnt < m) {
27                 int idx = id(p[hi++]);
28                 if(!vis[idx]) cnt++;
29                 vis[idx]++;
30             }
31             if(cnt < m) break;
32             if(ret > hi - lo && cnt == m) {
33                 ret = hi - lo;
34                 rl = lo, rr = hi - 1;
35             }
36             // printf("%d %d\n", lo, hi);
37             int idx = id(p[lo++]);
38             vis[idx]--;
39             if(vis[idx] == 0) cnt--;
40             if(lo >= n) break;
41         }
42         printf("%d\n", ret);
43         printf("%d %d\n", rl, rr);
44     }
45     return 0;
46 }

C:水题…

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 const int maxn = 100100;
 5 int n;
 6 int a[maxn], b[maxn];
 7
 8 int main() {
 9     // freopen("in", "r", stdin);
10     int T;
11     scanf("%d", &T);
12     while(T--) {
13         scanf("%d", &n);
14         int x = 0, y = 0;
15         for(int i = 1; i <= n; i++) {
16             scanf("%d%d",&a[i],&b[i]);
17         }
18         sort(a+1, a+n+1);
19         sort(b+1, b+n+1);
20         for(int i = 1; i <= n; i++) {
21             if(a[i] > b[i]) x += 2;
22             else if(a[i] == b[i]) x++, y++;
23             else y += 2;
24         }
25         if(x > y) puts("Winjourn");
26         else if(x == y) puts("Tie");
27         else puts("Never_Sorry");
28     }
29     return 0;
30 }

D:数位DP,dp(l,cnt)统计长度为l到时候1的个数为cnt的整数。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 typedef long long LL;
 5 const int maxn = 22;
 6 int digit[maxn];
 7 LL dp[maxn][maxn];
 8 LL n;
 9
10 LL dfs(int l, int cnt, bool flag) {
11     if(l == 0) return cnt;
12     if(!flag && ~dp[l][cnt]) return dp[l][cnt];
13     int pos = flag ? digit[l] : 9;
14     LL ret = 0;
15     for(int i = 0; i <= pos; i++) {
16         ret += dfs(l-1, cnt+(i==1), flag&&(pos==i));
17     }
18     if(!flag) dp[l][cnt] = ret;
19     return ret;
20 }
21
22 LL f(LL x) {
23     int pos = 0;
24     while(x) {
25         digit[++pos] = x % 10;
26         x /= 10;
27     }
28     return dfs(pos, 0, true);
29 }
30
31 int main() {
32     // freopen("in", "r", stdin);
33     int _ = 1;
34     memset(dp, -1, sizeof(dp));
35     while(~scanf("%lld", &n)) {
36         printf("Case %d:%lld\n", _++, f(n));
37     }
38     return 0;
39 }

E:模拟,如果循环节正好长度为50的话,就不要打省略号了。。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 vector<int> t1, t2;
 5 map<int, int> id;
 6 int a, b;
 7
 8 void f(int a, int b) {
 9     id.clear();
10     t1.clear(); t2.clear();
11     int p = -1;
12     while(1) {
13         t1.push_back(a/b);
14         int x = a % b;
15         if(x == 0) break;
16         if(id.find(x) == id.end()) {
17             id[x] = t2.size();
18             t2.push_back(x);
19         }
20         else {
21             p = id[x];
22             break;
23         }
24         a = x * 10;
25     }
26     if(t1.size() == 0) while(1);
27     printf("%d.", t1[0]);
28     bool flag = 0;
29     bool plusflag = 0;
30     int cnt = 0;
31     for(int i = 1; i < t1.size(); i++) {
32         if(cnt >= 50) {
33             plusflag = 1;
34             break;
35         }
36         if(i == p + 1) {
37             printf("(");
38             flag = 1;
39         }
40         printf("%d", t1[i]);
41         if(flag) cnt++;
42     }
43     if(plusflag) printf("...");
44     if(p >= 0) {
45         if(flag) printf(")\n");
46         printf("%d\n", t1.size()-p-1);
47     }
48     else {
49         printf("(0)\n");
50         printf("1\n");
51     }
52 }
53
54 int main() {
55     // freopen("in", "r", stdin);
56     // freopen("out", "w", stdout);
57     int _ = 1;
58     while(~scanf("%d%d",&a,&b)) {
59         printf("Case %d:\n%d/%d=", _++, a, b);
60         if(a % b == 0) printf("%d.(0)\n1\n", a / b);
61         else f(a, b);
62     }
63     return 0;
64 }

F:好麻烦的计算几何,感觉要先卡出封闭图形,之后找到所有的矩形。然后看看能放的最大圆。

G:对整个数组排序后二分答案,贪心地从左到右选取数字,保证相邻两个数的差不小于二分出来的值,判断是否满足大于等于k个。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 const int maxn = 100100;
 5 int n, k;
 6 int a[maxn], s[maxn];
 7 int ret;
 8
 9 bool ok(int dis) {
10     int i = 2, p = 1;
11     int cnt = 0;
12     while(i <= n) {
13         if(a[i] - a[p] >= dis) {
14             p = i; i++;
15             cnt++;
16         }
17         else i++;
18     }
19     return cnt + 1 >= k;
20 }
21
22 int main() {
23     // freopen("in", "r", stdin);
24     while(~scanf("%d%d",&n,&k)) {
25         memset(s, 0, sizeof(s));
26         for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
27         sort(a+1, a+n+1);
28         ret = a[n] - a[1];
29         int lo = 0, hi = a[n];
30         while(lo <= hi) {
31             int mid = (lo + hi) >> 1;
32             if(ok(mid)) {
33                 ret = mid;
34                 lo = mid + 1;
35             }
36             else hi = mid - 1;
37         }
38         printf("%d\n", ret);
39     }
40     return 0;
41 }

H:像是需要用启发式搜索将整座附近的点处理出来一个优先值,顺着第一条路走,最后回来。(后来有巨巨说是BFS)

I:枚举a,b字符串子串的起始,扫描对应位,如果不相同则替换至相同,最多k次操作。贪心地将替换操作放到前面,如果不能替换则break更新ret。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <string>
 6 #include <map>
 7 using namespace std;
 8
 9 const int maxn = 550;
10 int n, m, k;
11 char a[maxn], b[maxn];
12
13 int main() {
14     // freopen("in" ,"r", stdin);
15     while(~scanf("%d", &k)) {
16         scanf("%s%s",a,b);
17         n = strlen(a); m = strlen(b);
18         int ret = 0;
19         for(int i = 0; i < n; i++) {
20             for(int j = 0; j < m; j++) {
21                 int cnt = 0, tmp = 0;
22                 for(int aa = i, bb = j; aa < n && bb < m; aa++, bb++) {
23                     if(a[aa] == b[bb]) tmp++;
24                     else {
25                         if(cnt < k) tmp++, cnt++;
26                         else break;
27                     }
28                 }
29                 ret = max(ret, tmp);
30             }
31         }
32         printf("%d\n", ret);
33     }
34     return 0;
35 }

J:f(i,j)表示和为i,用j个数字组成的方案数,转移方程f(i,j)=f(i-p,j-1),p取1~4,会爆LL所以用double存了f。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 typedef long long LL;
 5 const int maxn = 111;
 6 const int maxm = 666;
 7 int n, m;
 8 double f[maxn][maxm];
 9
10 int main() {
11     // freopen("in", "r", stdin);
12     memset(f, 0, sizeof(f));
13     f[1][1] = 1.0; f[1][2] = 1.0; f[1][3] = 1.0; f[1][4] = 1.0;
14     for(int i = 2; i < maxn; i++) {
15         for(int j = 1; j < maxm; j++) {
16             for(int k = 1; k <= 4; k++) {
17                 if(k >= j) continue;
18                 f[i][j] += f[i-1][j-k];
19             }
20         }
21     }
22     while(~scanf("%d%d",&n,&m)) {
23         printf("%.4lf\n", f[n][m]/pow(4,n));
24     }
25     return 0;
26 }

K:最后的情形无非是两种,一种是wywy..,另一种是ywyw..。整个串长度如果是奇数那么是无法围成要求的项链的;之后判断当前情况和上述哪种情况最近,然后分别找w和y错位的数量,先交换,再修改,min(w,y)+(max(w,y)-min(w,y))=max(w,y)即为答案。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 const int maxn = 100100;
 5 char s[maxn], t[2][maxn];
 6 int n;
 7
 8 int main() {
 9     // freopen("in", "r", stdin);
10     memset(t, 0, sizeof(t));
11     for(int i = 0; i < maxn; i++) {
12         if(i % 2 == 0) {
13             t[0][i] = ‘w‘, t[1][i] = ‘y‘;
14         }
15         else {
16             t[0][i] = ‘y‘, t[1][i] = ‘w‘;
17         }
18     }
19     while(~scanf("%d", &n)) {
20         scanf("%s", s);
21         if(n & 1) {
22             puts("What a pity!");
23             continue;
24         }
25         int a = 0, b = 0;
26         for(int i = 0; i < n; i++) {
27             if(s[i] != t[0][i]) a++;
28             if(s[i] != t[1][i]) b++;
29         }
30         if(a < b) {
31             int w = 0, y = 0;
32             for(int i = 0; i < n; i++) {
33                 if(s[i] != t[0][i]) {
34                     if(s[i] == ‘w‘) w++;
35                     else y++;
36                 }
37             }
38             printf("%d\n", max(w, y));
39         }
40         else {
41             int w = 0, y = 0;
42             for(int i = 0; i < n; i++) {
43                 if(s[i] != t[1][i]) {
44                     if(s[i] == ‘w‘) w++;
45                     else y++;
46                 }
47             }
48             printf("%d\n", max(w, y));
49         }
50     }
51     return 0;
52 }

L:不会…

时间: 2024-12-25 09:54:44

青岛理工大学第五届ACM交流赛 部分题解的相关文章

2014山东省“浪潮杯”第五届ACM省赛总结

一次比赛做一次总结,弱菜又来总结了-- 我这种大四的又死皮赖来混省赛了,貌似就我和山大威海的某哥们(不详其大名)了吧.颁奖前和他聊天,得知他去百度了,真是不错,ORZ之. 比赛流水账: 题目目前不知道哪有,过几天填坑. 没发题目前,我们赌A题可能是水题,由于我是主coder,我去读A,剩下的一个从前往后,一个从后往前. 结果--,看到A有一个貌似是几何的图--,我还是硬头皮读了.读到一半,3分钟刷榜,发现E有出,让ZK读E,ZK先告诉我了B题题意,转而读E.B题是一个有环形关系的期望,我扫了一下

第七届省赛赛前交流赛部分题解

A题: Yougth's Game[Ⅲ]( 区间dp ) 这是在省赛前热身赛出的题目,可能是题目中有用到博弈的思想,很多人都在做,而且在尝试暴力.但是没有人往dp的方向上想. 题目类型:动态规划+博弈 分析:题意描述的很清楚,就是选择在两端取数,当前取的数不仅能够影响下一次的结果,而且能够影响后面的结果...又是一个求最优值,那么是不是可以往dp的方向上想了.区间dp 定义状态dp[ i ] [ j ] 为从 i 到 j 上A的得分,那么B的得分就是sum(i,j)-dp[ i ] [ j ]

开锁魔法II 哈尔滨理工大学第五届ACM程序设计竞赛

规律:a[i][j]=     1/i * a[i-1][j-1]      +      (i-1)/i * a[i-1][j];  (少一个盒子时使用j-1 次魔法的概率)   (少一个盒子时使用j次魔法的概率) 公式推导如下: 设a[i][j]为打开i个盒子正好需要j次魔法的情况. ① 1->1 ② 1->1 , 2->2;        两次 1->2 , 2->1;        一次 ③ 1->1 , 2->2 , 3->3;     三次 1-

青岛理工ACM交流赛 J题 数格子算面积

数格子算面积 Time Limit: 1000MS Memory limit: 262144K 题目描述 给你一个多边形(用’\’和’/’表示多边形的边),求多边形的面积. 输入 第一行两个正整数h 和 w (2 ≤ h, w ≤ 100),h是多边形所在平面的高,w是多边形所在平面的宽,接下来h行,每行w个字符,描述了整个平面的每个单元(每个单元是一个单位面积),字符只会是’\’,’/’和’.’其中之一,’\’,’/’表示多边形的边,’.’表示空白单元. 输出 输出一个数,输入代表的平面内多边

青岛理工交流赛 H题 素数间隙

13110581088注销 素数间隙 Time Limit: 1000MS Memory limit: 262144K 题目描述 Neko猫是一个很喜欢玩数字游戏的会说话的肥猫,经常会想到很多很好玩的数字游戏,有一天,它想到一个叫做素数间隙的游戏.据Neko猫的定义,素数间隙是两个相邻素数p和q组成的开区间[p, q),所以素数间隙的长度就是q-p. 例如7和11在素数表里是两个相邻的素数,所以7和11的素数间隙的长度为11-7,为4. 现在Neko猫会给你很多个正整数K(1<K≤1299710

2016 年宁波工程学院第七届ACM校赛题解报告

2016 年宁波工程学院第七届ACM校赛题解报告 本题解代码直接为比赛代码,仅供参考. A,B,C,D,G,H,J,K,L,M 来自 Ticsmtc 同学. F 来自 Gealo 同学. E,I 来自Alex 学长. Promblem A :    Two Sum 时间限制: 1 Sec  内存限制: 64 MB 题目描述: 给出n个数,另外给出?个整数S,判断是否可以从中取出2个数,使得这两个数的和是S. 输入: 第?行有个整数T(1 <= T <= 10),代表数据组数. 对于每组数据,第

我的第一次也将是最后一次的ACM省赛之旅

五月十二日,早7点47....头微痛, 昨天晚上从威海回来后通宵了一晚上. 现在想想,还是这么的飘忽,省赛落下了帷幕. 还记得,去的时候,多么雄心壮志,多么刻苦, 但是结果又是多么残酷. ACM还是积累的过程,短短两个月的训练,依旧无法弥补. 想起省赛的点点滴滴,还是唏嘘不已啊. 五月十日,我们乘车到威海,大约1小时车程,都在养精蓄锐. 到 哈工大(威海) 学苑餐厅(以后每一顿饭都是在那里吃的)吃了顿午饭. 然后下午 一点三十 集合,准备热身赛了. 两点,开始热身赛. 题目一发,马上就发现第二题

2014 ACM广东省赛总结

2014年广东省赛在化工大学城开,5月10日开幕式&热身赛,5月11日正式赛. 热身赛的时候,开幕式说有两小时,于是我们愉快的切题了,像平常组队赛那样很快出了两题,但卡在后面两题切不动了.这时候已经大概过了一小时十分钟了,于是开始各种测试调戏测评机.测的内容有:栈深.全局数组开的大小.dfs深度.TLE显示时间,各种提示错误RE CE PE WA TLE等等.可惜的是最后还没来得及测试PE,这也没办法,因为热身赛提前结束了,过了一小时四十分钟就结束了.以后热身赛可以考虑切完简单题就立刻跑去测试了

记TJPUのACM新生赛——Stay young, stay simple

刚看完国家德比来写点什么吧...话说比赛挺无聊,光头也真是命硬. 2016-12-3,12:00-17:00,TJPUのACM新生赛如期举行. 总体来说这次比赛体验还是比我第一次进行5小时比赛的浙江理工大学新生邀请赛要舒服的多(那次浙理工OJ直接爆了...) 然后凭着运气好和各位大佬的不杀之恩混到了第一... 比赛情况大概是上面图片那样,其实写出的题都挺水的,后面的DFS.BFS以及贪心什么的我都没多想...反正不会写. 唯一值得记录的大概是D题,HDOJ上有(5979),是2016ACM/IC