The 16th Zhejiang provincial collegiate programming contest

今天我挺有状态的,看过的题基本都给了正解(可能是昨晚cf div3打得跟屎一样,人品守恒,不好意思发题解了),自己也给队伍签了很多水题(不敢让队友写,怕出锅)。

最后6题滚了,有点可惜。还差B和K没做出来。

B我一眼就知道该怎么做了,推了一会发现相当可做,于是给队友嘴巴完队友写挂了 (有些小细节,比如判0什么的,下面的题解会讲)。

K有不同区间的做法一眼秒,没有的话就manacher,队友又写挂了 (弟弟们,怎么回事?

今天的训练我留意到一件事情,我跟队友讲题意的时候他们能听懂,但他们跟我讲题意的时候往往要讲好几遍。只要描述的过程中出现类似“这个”“那个”这样的代词我就完全不能接受,一定会让队友明确指出是什么东西。

以后训练我想刻意地让队友来讲题意,让他们多锻炼一下表达能力。

题目链接:http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=392


A:

要用到权值线段树的图论题,最少的情况很好想,最大的情况比较麻烦。听了金老师的solution,一如既往地没有听懂(挠头

晚点再拜读金老师的代码并更新博客。

B:

定义x,y为原始数组(样例已经给定)的值,x',y'为给定数组计算出来的值。显然可以作x-x',y-y'并提取公因式,计算一下(y-y')/(x-x')==a[i]+a[j]。到这里,解法已经很清晰了:枚举i,求j和a[j]并验证之。

细节有点恶心,要判x-x',y-y'是否为0。仔细点就可以过了。

 1 /* basic header */
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <cstdint>
 9 #include <climits>
10 #include <float.h>
11 /* STL */
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <queue>
16 #include <stack>
17 #include <algorithm>
18 #include <array>
19 #include <iterator>
20 /* define */
21 #define ll long long
22 #define dou double
23 #define pb emplace_back
24 #define mp make_pair
25 #define fir first
26 #define sec second
27 #define init(a,b) fill(begin(a),end(a),b)
28 #define sot(a,b) sort(a+1,a+1+b)
29 #define rep1(i,a,b) for(int i=a;i<=b;++i)
30 #define rep0(i,a,b) for(int i=a;i<b;++i)
31 #define repa(i,a) for(auto &i:a)
32 #define eps 1e-8
33 #define int_inf 0x3f3f3f3f
34 #define ll_inf 0x7f7f7f7f7f7f7f7f
35 #define lson curPos<<1
36 #define rson curPos<<1|1
37 /* namespace */
38 using namespace std;
39 /* header end */
40 
41 const int maxn = 1e5 + 10;
42 ll a[maxn], b[maxn], cnt[maxn];
43 int t;
44 
45 int main()
46 {
47     scanf("%d", &t);
48     while (t--)
49     {
50         ll n, x, y, curX = 0, curY = 0;
51         scanf("%lld%lld%lld", &n, &x, &y);
52         rep1(i, 1, n)
53         {
54             scanf("%lld", &a[i]); b[i - 1] = a[i];
55             cnt[i - 1] = 0;
56             curX += (i * a[i]); curY += (i * a[i] * a[i]);
57         }
58         ll deltaX = x - curX, deltaY = y - curY;
59         if (!deltaX && deltaY)
60         {
61             puts("0");
62             continue;
63         }
64         if (!deltaX && !deltaY)
65         {
66             ll ans = 0;
67             sort(b, b + n);
68             int m = unique(b, b + n) - b;
69             rep1(i, 1, n)
70             cnt[lower_bound(b, b + m, a[i]) - b]++;
71             rep0(i, 0, m)
72             ans += 1LL * cnt[i] * (cnt[i] - 1) / 2;
73             printf("%lld\n", ans);
74             continue;
75         }
76         if (abs(deltaY) % abs(deltaX))
77         {
78             puts("0");
79             continue;
80         }
81         ll rough = deltaY / deltaX, ans = 0;
82         for (ll i = 1; i <= n; i++)
83         {
84             ll fm = rough - 2 * a[i], fs = deltaX / fm, j = i - fs;
85             if (!fm) continue;
86             if (abs(deltaX) % abs(fm)) continue;
87             if (j <= n && j >= 1)
88                 if (a[i] + a[j] == rough) ans++;
89         }
90         printf("%lld\n", ans / 2);
91     }
92     return 0;
93 }
View Code

C:

这个题给队友喂了好多假算法,都被队友hack掉了,有点迷。感觉是个姿势非常奇怪的贪心。

D:

有向图求欧拉路(貌似?我还挺想写的,但是最后的时间都在调B和K,难受

E:

sort一下,倒着判就完事了。

 1 /* basic header */
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <cstdint>
 9 #include <climits>
10 #include <float.h>
11 /* STL */
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <queue>
16 #include <stack>
17 #include <algorithm>
18 #include <array>
19 #include <iterator>
20 /* define */
21 #define ll long long
22 #define dou double
23 #define pb emplace_back
24 #define mp make_pair
25 #define fir first
26 #define sec second
27 #define init(a,b) fill(begin(a),end(a),b)
28 #define sot(a,b) sort(a+1,a+1+b)
29 #define rep1(i,a,b) for(int i=a;i<=b;++i)
30 #define rep0(i,a,b) for(int i=a;i<b;++i)
31 #define repa(i,a) for(auto &i:a)
32 #define eps 1e-8
33 #define int_inf 0x3f3f3f3f
34 #define ll_inf 0x7f7f7f7f7f7f7f7f
35 #define lson curPos<<1
36 #define rson curPos<<1|1
37 /* namespace */
38 using namespace std;
39 /* header end */
40 
41 const int maxn = 1e5 + 10;
42 int n, a[maxn], b[maxn], ans;
43 
44 int main()
45 {
46     int t; scanf("%d", &t);
47     while (t--)
48     {
49         scanf("%d", &n);
50         rep1(i, 1, n) scanf("%d", &a[i]), b[i] = a[i];
51         sot(b, n);
52         ans = n;
53         for (int i = n; i >= 1; i--)
54             if (a[i] == b[ans]) ans--;
55         printf("%d\n", ans);
56     }
57     return 0;
58 }
View Code

F:

没什么意思的细节签到题。

 1 /* basic header */
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <cstdint>
 9 #include <climits>
10 #include <float.h>
11 /* STL */
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <queue>
16 #include <stack>
17 #include <algorithm>
18 #include <array>
19 #include <iterator>
20 /* define */
21 #define ll long long
22 #define dou double
23 #define pb emplace_back
24 #define mp make_pair
25 #define fir first
26 #define sec second
27 #define init(a,b) fill(begin(a),end(a),b)
28 #define sot(a,b) sort(a+1,a+1+b)
29 #define rep1(i,a,b) for(int i=a;i<=b;++i)
30 #define rep0(i,a,b) for(int i=a;i<b;++i)
31 #define repa(i,a) for(auto &i:a)
32 #define eps 1e-8
33 #define int_inf 0x3f3f3f3f
34 #define ll_inf 0x7f7f7f7f7f7f7f7f
35 #define lson curPos<<1
36 #define rson curPos<<1|1
37 /* namespace */
38 using namespace std;
39 /* header end */
40 
41 set<char>ss = { 'a', 'e', 'i', 'y', 'o', 'u' };
42 const int maxn = 200;
43 char s[maxn];
44 int t;
45 
46 int main()
47 {
48     scanf("%d", &t);
49     while (t--)
50     {
51         scanf("%s", s + 1);
52         int len = strlen(s + 1);
53         printf("%c", s[1]);
54         rep1(i, 2, len)
55         if (ss.count(s[i])) continue;
56         else printf("%c", s[i]);
57         puts("");
58     }
59     return 0;
60 }
View Code

G:

温暖人心。

 1 #include <bits/stdc++.h>
 2 /* define */
 3 #define ll long long
 4 #define dou double
 5 #define pb emplace_back
 6 #define mp make_pair
 7 #define fir first
 8 #define sec second
 9 #define init(a,b) fill(begin(a),end(a),b)
10 #define sot(a,b) sort(a+1,a+1+b)
11 #define rep1(i,a,b) for(int i=a;i<=b;++i)
12 #define rep0(i,a,b) for(int i=a;i<b;++i)
13 #define repa(i,a) for(auto &i:a)
14 #define eps 1e-8
15 #define int_inf 0x3f3f3f3f
16 #define ll_inf 0x7f7f7f7f7f7f7f7f
17 #define lson curPos<<1
18 #define rson curPos<<1|1
19 /* namespace */
20 using namespace std;
21 /* header end */
22 
23 int t, n;
24 
25 int main()
26 {
27     scanf("%d", &t);
28     while (t--)
29     {
30         scanf("%d", &n);
31         for (int i = n;; i++)
32         {
33             if (i % 7 == 0 && i % 4 != 0)
34             {
35                 printf("%d\n", i);
36                 break;
37             }
38         }
39     }
40     return 0;
41 }
View Code

H:

水题,计算出原有极值个数p,答案显然只有p-0,p-1,p-2三种情况(样例太恶臭了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 
 5 using namespace std;
 6 const int maxn = 2000000;
 7 int A[maxn];
 8 int fg[maxn];
 9 int main()
10 {
11     int T;
12     scanf("%d",&T);
13     while(T--){
14         int n;
15         scanf("%d",&n);
16         for(int i = 1;i <= n;i++){
17             scanf("%d",&A[i]);
18             fg[i] = 0;
19         }
20         if(n <= 3){
21             printf("0\n");
22             continue;
23         }
24         int ans = 0;
25         for(int i = 2;i <= n-1;i++){
26             if(A[i-1] < A[i] &&A[i] > A[i+1]){
27                 ans ++;
28                 fg[i] = 1;
29             }
30         }
31         // for(int i = 1;i <= n;i++)
32         //     printf("%d ",A[i]);
33         // printf("\n");
34         // for(int i = 1;i <= n;i++)
35         //     printf("%d ",fg[i]);
36         // printf("\n");
37         int endflag = 0; 
38         for(int i = 2;i <= n-2;i++){
39             if(fg[i] == 1&&fg[i + 2] == 1){
40                 if(A[i] == A[i + 2]){
41                     printf("%d\n",ans-2);
42                     endflag = 1;
43                     break;
44                 }
45             }
46         }
47         if(endflag) continue;
48         for(int i = 2;i <= n-2;i++){
49             if(fg[i] == 1){
50                 if(A[i-1] < A[i+1]&&A[i+1] > A[i+2]){
51                     continue;
52                 }else if(A[i-2] < A[i-1]&&A[i-1] > A[i+1]) {
53                     continue;
54                 }else{
55                     printf("%d\n",ans-1);
56                     endflag = 1;
57                     break;
58                 }
59             }
60         }
61         if(endflag) continue;
62         printf("%d\n",ans);
63     }
64     return 0;
65 }
View Code

I:

看完题之后队友马上给结论:判读进来的数模3余几即可,虽然我没有听得很懂,不过看队友一脸坚定我还是光速敲了。奇偶性貌似是看能不能被3整除,研究一下就知道了。

 1 /* basic header */
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <cstdint>
 9 #include <climits>
10 #include <float.h>
11 /* STL */
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <queue>
16 #include <stack>
17 #include <algorithm>
18 #include <array>
19 #include <iterator>
20 /* define */
21 #define ll long long
22 #define dou double
23 #define pb emplace_back
24 #define mp make_pair
25 #define fir first
26 #define sec second
27 #define init(a,b) fill(begin(a),end(a),b)
28 #define sot(a,b) sort(a+1,a+1+b)
29 #define rep1(i,a,b) for(int i=a;i<=b;++i)
30 #define rep0(i,a,b) for(int i=a;i<b;++i)
31 #define repa(i,a) for(auto &i:a)
32 #define eps 1e-8
33 #define int_inf 0x3f3f3f3f
34 #define ll_inf 0x7f7f7f7f7f7f7f7f
35 #define lson curPos<<1
36 #define rson curPos<<1|1
37 /* namespace */
38 using namespace std;
39 /* header end */
40 
41 const int maxn = 1e4 + 10;
42 char a[maxn], b[maxn];
43 
44 int main()
45 {
46     int t;
47     scanf("%d", &t);
48     while (t--)
49     {
50         scanf("%s", a + 1); scanf("%s", b + 1);
51         int len1 = strlen(a + 1), len2 = strlen(b + 1);
52         int sum1 = 0, sum2 = 0, sign1 = 1, sign2 = 1;
53         rep1(i, 1, len1) sum1 += a[i] - '0';
54         rep1(i, 1, len2) sum2 += b[i] - '0';
55         if (sum1 % 3 == 2) sign1 = 2; if (sum2 % 3 == 1) sign2 = 2;
56         printf("%d\n", abs(sign1 - sign2) % 2);
57     }
58     return 0;
59 }
View Code

J:

DSU水题,队友居然写挂了要批评,还是我改对的。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 2000000;
 4 int pa[maxn];
 5 
 6 int find(int x)
 7 {
 8     if (pa[x] == x) return x;
 9     else return pa[x] = find(pa[x]);
10 }
11 priority_queue<int, vector<int>, greater<int> > Q;
12 vector<int> G[maxn];
13 int vis[maxn], visit[maxn];
14 
15 int main()
16 {
17     int T;
18     scanf("%d", &T);
19     while (T--)
20     {
21         int n, m;
22         scanf("%d%d", &n, &m);
23         for (int i = 1; i <= n; i++)
24         {
25             pa[i] = i;
26             vis[i] = 0;
27             visit[i] = 0;
28             G[i].clear();
29         }
30         for (int i = 1; i <= m; i++)
31         {
32             int a, b;
33             scanf("%d%d", &a, &b);
34             if (a > b) swap(a, b);
35             G[a].push_back(b);
36             G[b].push_back(a);
37             int x = find(a);
38             int y = find(b);
39             pa[y] = x;
40         }
41         int ans = 0;
42         for (int i = 1; i <= n; i++)
43         {
44             if (find(i) == i) ans ++;
45         }
46         printf("%d\n", ans);
47         while (!Q.empty()) Q.pop();
48         for (int i = 1; i <= n; i++)
49         {
50             if (vis[pa[i]] == 0)
51             {
52                 Q.push(i);
53                 vis[pa[i]] = 1;
54                 visit[i] = 1;
55             }
56         }
57         int flag = 0;
58         while (!Q.empty())
59         {
60             int x = Q.top();
61             Q.pop();
62             if (flag == 0)
63             {
64                 printf("%d", x);
65                 flag = 1;
66             }
67             else printf(" %d", x);
68             for (int i = 0; i < G[x].size(); i++)
69             {
70                 if (!visit[G[x][i]])
71                 {
72                     visit[G[x][i]] = 1;
73                     Q.push(G[x][i]);
74                 }
75             }
76         }
77         printf("\n");
78     }
79     return 0;
80 }
View Code

K:

和队友讨论了一会口A了。如果存在不相同子串的区间,那么选定一个尽量小的“能包含所有不相同子串区间”的区间,然后往两边扩展即可。

如果不存在不相同子串的区间,直接跑manacher算回文子串个数就完事了 (天知道为什么队友会写挂这题。

L && M:

看到没有人过就溜了。

猜你喜欢

转载自www.cnblogs.com/JHSeng/p/10780537.html