Codeforces Round #557 (div.2)

时间太晚了就没有打(居然01:05,该歇了),不算难,但很有意思,后面的题目质量不错。

题目链接:http://codeforces.com/contest/1162


A:

照例是开局送温暖。

 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 sot(a,b) sort(a+1,a+1+b)
28 #define rep1(i,a,b) for(int i=a;i<=b;++i)
29 #define rep0(i,a,b) for(int i=a;i<b;++i)
30 #define repa(i,a) for(auto &i:a)
31 #define eps 1e-8
32 #define int_inf 0x3f3f3f3f
33 #define ll_inf 0x7f7f7f7f7f7f7f7f
34 #define lson curPos<<1
35 #define rson curPos<<1|1
36 /* namespace */
37 using namespace std;
38 /* header end */
39 
40 const int maxn = 60;
41 int n, h, m, a[maxn];
42 ll ans = 0;
43 
44 int main()
45 {
46     scanf("%d%d%d", &n, &h, &m);
47     rep1(i, 1, n) a[i] = h;
48     while (m--)
49     {
50         int l, r, x; scanf("%d%d%d", &l, &r, &x);
51         rep1(i, l, r) a[i] = min(a[i], x);
52     }
53     rep1(i, 1, n) ans += pow(a[i], 2);
54     printf("%lld\n", ans);
55     return 0;
56 }
View Code

B:

我还想了一下无脑比大小会不会错,写了几个我觉得对的if都挂了。反而无脑比大小就能A。

 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 sot(a,b) sort(a+1,a+1+b)
28 #define rep1(i,a,b) for(int i=a;i<=b;++i)
29 #define rep0(i,a,b) for(int i=a;i<b;++i)
30 #define repa(i,a) for(auto &i:a)
31 #define eps 1e-8
32 #define int_inf 0x3f3f3f3f
33 #define ll_inf 0x7f7f7f7f7f7f7f7f
34 #define lson curPos<<1
35 #define rson curPos<<1|1
36 /* namespace */
37 using namespace std;
38 /* header end */
39 
40 const int maxn = 51;
41 int a[maxn][maxn], b[maxn][maxn], n, m;
42 
43 int main()
44 {
45     scanf("%d%d", &n, &m);
46     rep1(i, 1, n) rep1(j, 1, m) scanf("%d", &a[i][j]);
47     rep1(i, 1, n) rep1(j, 1, m)
48     {
49         scanf("%d", &b[i][j]);
50         if (a[i][j] > b[i][j]) swap(a[i][j], b[i][j]);
51     }
52     int flag = 1;
53     rep1(i, 1, n) rep1(j, 2, m)
54     if (a[i][j] <= a[i][j - 1] || b[i][j] <= b[i][j - 1])
55         flag = 0;
56     rep1(j, 1, m) rep1(i, 2, n)
57     if (a[i][j] <= a[i - 1][j] || b[i][j] <= b[i - 1][j])
58         flag = 0;
59     if (flag) puts("Possible"); else puts("Impossible");
60     return 0;
61 }
View Code

C:

看完题意觉得很有意思。

题意类似于猜数字,甲在1到n的范围内设定了一个数字让乙猜,乙有一个长度为k的猜测序列,每次猜都会拿出猜测序列最前面的数字问甲对不对,若得到否定的答案,则用下一个数字继续猜。

甲有一次作弊的机会,在某次猜测之前或之后,把设定好的数字x变为x+1或x-1。问甲最多能给出多少次否定的答案。

题意可以转化一下。在[1..n]这个区间中,有多少对p和q(用过了就不能再用)满足abs(p-q)<=1并且存在一个数i使得p不出现在x[1..i],q不出现在x[i+1..k]中。

统计O(k),数合法的pq只需O(n)。算是最近contest里不错的题。

 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 sot(a,b) sort(a+1,a+1+b)
28 #define rep1(i,a,b) for(int i=a;i<=b;++i)
29 #define rep0(i,a,b) for(int i=a;i<b;++i)
30 #define repa(i,a) for(auto &i:a)
31 #define eps 1e-8
32 #define int_inf 0x3f3f3f3f
33 #define ll_inf 0x7f7f7f7f7f7f7f7f
34 #define lson curPos<<1
35 #define rson curPos<<1|1
36 /* namespace */
37 using namespace std;
38 /* header end */
39 
40 const int maxn = 1e5 + 10;
41 int n, k, a[maxn], l[maxn], r[maxn];
42 
43 int main()
44 {
45     scanf("%d%d", &n, &k);
46     int ans = (n - 2) * 3 + 4; //答案最大可能值
47     rep1(i, 1, k)
48     {
49         scanf("%d", &a[i]);
50         r[a[i]] = i; //记录a[i]在查询数组最右边的位置
51         if (!l[a[i]]) l[a[i]] = i; //记录a[i]在查询数组最左边的位置
52     }
53     rep1(i, 1, n)
54     {
55         if (!l[i]) continue; //说明没出现过这个数字,直接忽略
56         if (i == 1) //这里把所有不符合答案的情况都排除掉,首尾要特判一下
57         {
58             if (r[2] && l[1] < r[2]) ans--;
59         }
60         else if (i == n)
61         {
62             if (r[n - 1] && l[n] < r[n - 1]) ans--;
63         }
64         else
65         {
66             if (l[i] < r[i + 1]) ans--;
67             if (l[i] < r[i - 1]) ans--;
68         }
69         if (l[i]) ans--;
70     }
71     printf("%d\n", ans);
72     return 0;
73 }
View Code

D:

给定n个绕着圆周均匀分布的点和m条线段(线段的端点都是圆周上的点),问是否存在不超过n的整数k,把圆周旋转k个单位(圆周上相邻两个点之间旋转的度数称为一个单位),使得该图像旋转对称。

其实就是问是否存在这样的k,对所有的a,b满足:若(a,b)为线段,则((a+k)%n,(b+k)%n)依然为线段。

这等价于检查(a+i*gcd(n,k),b+i*gcd(n,k))是否为线段,很显然时间复杂度O(m*d(n))。

然而官方solution有个更好的做法,时间复杂度O(mlogm),原文如下:

There is also a faster linear time solution. We can reduce this to a problem of finding the largest period of a string. For every point, we can sort the length of the segments starting from that point (length in this case refers to clockwise distance). We also add some null character to denote a point. For instance, the first sample case's string might start like 2,1,1,4,8,10,1, that represent the points from 1 to 3. Such a string can be computed in O(mlogm) time. Then, after finding this string, we just want to check the period is bigger than 1. Let w be the length of the string. We can find this by concatenating the string to itself, then use z-algorithm to check if there is any is any index i from 1 to w1 that is at least w.

 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 sot(a,b) sort(a+1,a+1+b)
28 #define rep1(i,a,b) for(int i=a;i<=b;++i)
29 #define rep0(i,a,b) for(int i=a;i<b;++i)
30 #define repa(i,a) for(auto &i:a)
31 #define eps 1e-8
32 #define int_inf 0x3f3f3f3f
33 #define ll_inf 0x7f7f7f7f7f7f7f7f
34 #define lson curPos<<1
35 #define rson curPos<<1|1
36 /* namespace */
37 using namespace std;
38 /* header end */
39 
40 const int maxn = 1e5 + 10;
41 vector<int> a[maxn];
42 int n, m;
43 
44 int main()
45 {
46     scanf("%d%d", &n, &m);
47     while (m--)
48     {
49         int x, y; scanf("%d%d", &x, &y); x--; y--;
50         if (x > y) swap(x, y);
51         if (abs(x - y) > n / 2) swap(x, y);
52         a[x].pb(min(abs(x - y), n - abs(x - y)));
53         if (abs(x - y) == n / 2) a[y].pb(n / 2);
54     }
55     rep0(i, 0, n) sort(a[i].begin(), a[i].end());
56     rep1(i, 1, n / 2)
57     if (n % i == 0)
58     {
59         for (int j = i; j < n; j += i)
60             for (int k = j; k < j + i; k++)
61                 if (a[k] != a[k - i]) goto mark;
62         return puts("Yes"), 0;
63 mark:;
64     }
65     puts("No");
66     return 0;
67 }
View Code

E:

标题就暴露是Nim游戏相关。晚点再补 (咕咕咕

猜你喜欢

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