Codeforces Round #354 (Div. 2)

5/5

水了场CF,写个水水地题解~~

题A CodeForces 676A

题意:给你一个排列,问你交换一次,最大最小位置最远是多少?

题解:暴力交换,暴力算,反正数据小.偷懒被hack更惨!!

 1 /*zhen hao*/
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4
 5 #define lson l, m, rt*2
 6 #define rson m + 1, r, rt*2+1
 7 #define xx first
 8 #define yy second
 9
10 typedef pair<int,int> pii;
11 typedef long long ll;
12 typedef unsigned long long ull;
13
14 int s[110], n;
15
16 int cal() {
17   int p1, m1 = 110, p2, m2 = -110;
18   for (int i = 1; i <= n; i++) {
19     if (m1 > s[i]) m1 = s[i], p1 = i;
20     if (m2 < s[i]) m2 = s[i], p2 = i;
21   }
22   int ret = abs(p1 - p2);
23   return ret;
24 }
25
26 int main() {
27 //  freopen("case.in", "r", stdin);
28   cin >> n;
29   for (int i = 1; i <= n; i++) cin >> s[i];
30   int ans = 0;
31   for (int i = 1; i <= n; i++)
32     for (int j = i + 1; j <= n; j++) {
33       swap(s[i], s[j]);
34       ans = max(ans, cal());
35       swap(s[i], s[j]);
36     }
37   printf("%d\n", ans);
38   return 0;
39 }

代码君

题B CodeForces 676B

题意:给你n层杯子叠起来,然后往上面开始倒水,1s满一个杯子,问你最后又多少个杯子是满的?

题解:数据小,直接模拟,写个dfs即可。

 1 /*zhen hao*/
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4
 5 #define lson l, m, rt*2
 6 #define rson m + 1, r, rt*2+1
 7 #define xx first
 8 #define yy second
 9
10 typedef pair<int,int> pii;
11 typedef long long ll;
12 typedef unsigned long long ull;
13
14 int n, t;
15 int v[110][2];
16 double cnt[1100];
17
18 void init() {
19   int cur = 1;
20   for (int i = 1; i < 11; i++) {
21     for (int j = 0; j < i; j++) {
22       v[cur][0] = cur + i;
23       v[cur][1] = cur + i + 1;
24 //      cout << cur << ‘ ‘ << v[cur][0] << ‘ ‘ << v[cur][1] << endl;
25       cur++;
26     }
27   }
28 }
29
30 void dfs(int d, int cur, double add) {
31   cnt[cur] += add;
32   if (d >= n) return;
33   if (cnt[cur] > 1.0) {
34     double flow = cnt[cur] - 1.0;
35     cnt[cur] = 1.0;
36     dfs(d + 1, v[cur][0], flow / 2);
37     dfs(d + 1, v[cur][1], flow / 2);
38   }
39 }
40
41 int main() {
42 //  freopen("case.in", "r", stdin);
43   init();
44   cin >> n >> t;
45   for (int i = 0; i < t; i++) {
46     dfs(0, 1, 1.0);
47   }
48   int ans = 0;
49   for (int i = 1; i <= n * (n + 1) / 2; i++) if (cnt[i] >= 1.0) ans++;
50   cout << ans << endl;
51   return 0;
52 }

代码君

题C CodeForces 676C

题意:给你个字符串,只有a和b,然后可以改k个,问你最长连续是多少?

题解:好像可以用单调队列搞,我没想这么多,就用了个二分答案。

 1 /*zhen hao*/
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4
 5 #define lson l, m, rt*2
 6 #define rson m + 1, r, rt*2+1
 7 #define xx first
 8 #define yy second
 9
10 typedef pair<int,int> pii;
11 typedef long long ll;
12 typedef unsigned long long ull;
13
14 const int maxn = 1e5 + 100;
15 char s[maxn];
16 int n, k, len;
17 int cnta[maxn], cntb[maxn];
18
19 bool check(int m) {
20   int best = min(cnta[m - 1], cntb[m - 1]);
21   for (int i = 1; i + m <= len; i++) {
22     int tmp = min(cnta[i + m - 1] - cnta[i - 1], cntb[i + m - 1] - cntb[i - 1]);
23     best = min(best, tmp);
24   }
25   return best <= k;
26 }
27
28 int main() {
29 //  freopen("case.in", "r", stdin);
30   cin >> n >> k;
31   scanf("%s", s);
32   len = strlen(s);
33   int a = 0, b = 0, L = 0, R = len + 1;
34   for (int i = 0; i < len; i++) {
35     if (s[i] == ‘a‘) a++; else b++;
36     cnta[i] = a; cntb[i] = b;
37 //    cout << a << ‘ ‘ << b << endl;
38   }
39   while (R - L > 1) {
40     int M = (R + L) / 2;
41     if (check(M)) L = M;
42     else R = M;
43   }
44   printf("%d\n", L);
45   return 0;
46 }

代码君

题D CodeForces 676D

题意:给你一个地图,除了‘*’是没有门的其他字符都有相应的门,每次操作可以到对应的门,也可以翻转这个点,然后代价是所有点也同时向顺时针翻转,然后给你起点和终点,问你最小花多少时间。

题解:没看到所有点都翻转,然后码了个最短路,GG。如果所有都可以翻转的话,显然可以用bfs。具体做法是,先用一个can[i][j][k][l]表示当前翻转的面是i面,然后j表示方向,k和l表示位置,先得到第0面,然后可以用一个for循环得到1、2、 3面的情况,然后就是很普通的bfs了。

 1 /*zhen hao*/
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4
 5 #define lson l, m, rt*2
 6 #define rson m + 1, r, rt*2+1
 7 #define xx first
 8 #define yy second
 9
10 typedef pair<int,int> pii;
11 typedef long long ll;
12 typedef unsigned long long ull;
13
14 const int maxn = 1e3 + 10, dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
15 char maze[maxn][maxn];
16 int vis[4][maxn][maxn], can[5][5][maxn][maxn];
17 int n, m, xt, yt, xm, ym;
18
19 struct Node {
20   int x, y, c, d;
21   Node(int x=0, int y=0, int c=0, int d=0) : x(x), y(y), c(c), d(d) {}
22 };
23
24 void init_graph() {
25   memset(can, 0, sizeof can);
26     for (int i = 0; i < n; i++)
27       for (int j = 0; j < m; j++) {
28         if(maze[i][j] == ‘+‘) can[0][0][i][j] = can[0][1][i][j] = can[0][2][i][j] = can[0][3][i][j] = 1;
29         if(maze[i][j] == ‘U‘) can[0][1][i][j] = can[0][2][i][j] = can[0][3][i][j] = 1;
30         if(maze[i][j] == ‘R‘) can[0][0][i][j] = can[0][2][i][j] = can[0][3][i][j] = 1;
31         if(maze[i][j] == ‘D‘) can[0][0][i][j] = can[0][1][i][j] = can[0][3][i][j] = 1;
32         if(maze[i][j] == ‘L‘) can[0][0][i][j] = can[0][1][i][j] = can[0][2][i][j] = 1;
33         if(maze[i][j] == ‘-‘) can[0][1][i][j] = can[0][3][i][j] = 1;
34         if(maze[i][j] == ‘|‘) can[0][0][i][j] = can[0][2][i][j] = 1;
35         if(maze[i][j] == ‘^‘) can[0][0][i][j] = 1;
36         if(maze[i][j] == ‘>‘) can[0][1][i][j] = 1;
37         if(maze[i][j] == ‘v‘) can[0][2][i][j] = 1;
38         if(maze[i][j] == ‘<‘) can[0][3][i][j] = 1;
39       }
40     for (int x = 1; x < 4; x++)
41       for (int i = 0; i < n; i++)
42         for (int j = 0; j < m; j++)
43           for (int k = 0; k < 4; k++)
44             can[x][(k + 1) % 4][i][j] = can[x - 1][k][i][j];
45 }
46
47 int bfs() {
48   queue<Node> q;
49   q.push(Node(xt, yt, 0, 0));
50   memset(vis, false, sizeof vis);
51   vis[0][xt][yt] = 1;
52   while (!q.empty()) {
53     Node r = q.front(); q.pop();
54     if (r.x == xm && r.y == ym) return r.d;
55
56     for (int i = 0; i < 4; i++) if (can[r.c][i][r.x][r.y]) {
57       int nx = r.x + dx[i], ny = r.y + dy[i];
58       if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
59       if (vis[r.c][nx][ny] || !can[r.c][(i + 2) % 4][nx][ny]) continue;
60       vis[r.c][nx][ny] = 1;
61       q.push(Node(nx, ny, r.c, r.d + 1));
62     }
63
64     int nc = (r.c + 1) % 4;
65     if (vis[nc][r.x][r.y]) continue;
66     vis[nc][r.x][r.y] = 1;
67     q.push(Node(r.x, r.y, nc, r.d + 1));
68   }
69   return -1;
70 }
71
72 int main() {
73 //  freopen("case.in", "r", stdin);
74   cin >> n >> m;
75   for (int i = 0; i < n; i++) {
76     scanf("%s", maze[i]);
77   }
78   scanf("%d%d%d%d", &xt, &yt, &xm, &ym);
79   xt--; yt--; xm--; ym--;
80 //  cout << xt << ‘ ‘ << yt << endl;
81   init_graph();
82   printf("%d\n", bfs());
83   return 0;
84 }

代码君

题E CodeForces 676E

题意:给你一个多项式:

P(x) = anxn + an - 1xn - 1 + ... + a1x + a0

然后另Q(x) = x - k,两个人轮流填系数使得Q(x)|P(x),也就是存在B(x)使得P(x) = B(x)Q(x)成立,现在可能已经进行了一部分,问你继续玩能不能够获胜?

题解:完全没思路,弃疗了。百度了多项式除法也不会做,然后即参照这位老兄的题解

主要突破点是找做完除法后的余数,既然是余数,那么P(x)减去余数必然能够被Q(x)整除,那么设这个余数是J,然后满足Q(x)|(P(x)-J),怎么得到这个J呢?从P(x)出发,要每一项都得到一个(x-k)的公因子,那不就可以被Q(x)整除了吗?所以

J = ankn + an - 1kn - 1 + ... + a1k + a0,因为P(x) - J = an(x - k)(...) + an - 1(x - k) (...) + a1(x - k),所以只要让这个J = 0就说明可以整除了,之后的情况就像上述博客说的那样了。最后提醒一点是:用这个博客的随机数的方法可以过,将数设为数据没有考虑的一个数也可以过。

 1 /*zhen hao*/
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4
 5 typedef long long ll;
 6 const int maxn = 1e5 + 10, mod = 100003619;
 7 int a[maxn], t[maxn], n, k;
 8 char s[110];
 9
10 int main() {
11 //  freopen("case.in", "r", stdin);
12   cin >> n >> k;
13   int ok = 0, c = 0;
14   for (int i = 0; i <= n; i++) {
15     scanf("%s", s);
16     if (s[0] == ‘?‘) ok = 1;
17     else {
18       t[i] = 1;
19       sscanf(s, "%d", a + i);
20       c ^= 1;
21     }
22   }
23   if (k == 0) {
24     if (t[0]) puts(a[0] == 0 ? "Yes" : "No");
25     else puts(c & 1 ? "Yes" : "No");
26   } else {
27     if (ok) puts(n & 1 ? "Yes" : "No");
28     else {
29       ll res = 0;
30       for (int i = n; i >= 0; i--) {
31         res = res * k + a[i];
32         res %= mod;
33       }
34       puts(res == 0 ? "Yes" : "No");
35     }
36   }
37   return 0;
38 }

代码君

时间: 2024-10-21 10:00:29

Codeforces Round #354 (Div. 2)的相关文章

Codeforces Round #354 (Div. 2) ABCD

Codeforces Round #354 (Div. 2) Problems # Name     A Nicholas and Permutation standard input/output 1 s, 256 MB    x3384 B Pyramid of Glasses standard input/output 1 s, 256 MB    x1462 C Vasya and String standard input/output 1 s, 256 MB    x1393 D T

Codeforces Round #354 (Div. 2) B. Pyramid of Glasses (模拟+思维)

原题请戳这里 题意: 将杯子摆成杨辉三角状,即顶层1个杯子,第二层2个杯子,……第N层N个杯子. 每一秒能倒满1个杯子,每次一个杯子满了,酒会平分得流入它下面支撑它的两个杯子中. 如下图所示.1 ≤ n ≤ 10, 0 ≤ t ≤ 10 000. 分析:由于n很小,所以直接模拟此过程,其实也是一个递推的过程. 注意,如果递推的时候没有递推到n+1层,那么最后统计的时候是统计>=1的个数而不是==1的个数, 因为当酒能倒满的杯子大于n层杯子即n*(n+1)/2<t时,递推过程终止于n层,不能向下

Codeforces Round #354 (Div. 2) C. Vasya and String

题目大意:有一个(a|b)^N的由a和b构成的长度为N的字符串,允许修改其中k位.问能构成的最长的全为a或全为b的子串的长度最长为多少. 思路,用两个队列分别保存前K+1个a和b的位置,以i为结尾的最长的子串的长度就是i减去队列头元素的值. #include <iostream> #include <cstdio> #include <memory.h> #include <queue> using namespace std; int main(int a

Codeforces Round #354 (Div. 2) - B. Pyramid of Glasses

/* 队友告知的题意,大概是 杯子如题摆放,有 n 层 .最上面那个杯子一秒钟可以装满, 给出 n 和时间 t ,问 t 秒后可以装满多少个杯子. 大致思路是 使用二维数组模拟杯子往下漏水的过程. 最后扫一遍数组计算容量大于 1 的个数 . */ #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> using name

Codeforces Round #354 (Div. 2) A

题目给出1~n的n个数的一个permutation,swap一次任意两个数,output 1 and n 之间的最大距离 记录1 and n的位置p,确定1的位置,移动n到位置1 and n,确定n的位置,移动1到位置1 and n,output max value. O(n). #include <cstdio> #include <cmath> #include <algorithm> using namespace std; int n; struct node{

Codeforces Round #279 (Div. 2) ABCD

Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name     A Team Olympiad standard input/output 1 s, 256 MB  x2377 B Queue standard input/output 2 s, 256 MB  x1250 C Hacking Cypher standard input/output 1 s, 256 MB  x740 D Chocolate standard input/

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我