Codeforces Round #648 (Div. 2)
或许更好的阅读体验
A:Matrix Game
思路
题意可以说是非常简单的,我们选定的格子的行列都不能存在1,可以发现我们可以放的格子一定是固定的,然后这题就变成了技术总共可以放多少个棋子了,所以我们直接开两个数组记录一下行列是否有1存在,再通过暴力求解的到可放的格子的数量就行,具体看代码注释吧。
代码
#include <bits/stdc++.h>using namespace std;typedef long long ll;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N = 55;int a[N][N], n, m, c[N], r[N];int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false);int t = read();while(t--) {n = read(), m = read();memset(c, 0, sizeof c);memset(r, 0, sizeof r);for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++) {a[i][j] = read();if(a[i][j]) c[i] = 1, r[j] = 1;//r[i]表示这一行是否有1,c[j]表示这一列是否有1,}int sum = 0;for(int i = 1; i <= n; i++) {//枚举行。if(c[i]) continue;//如果这一行是有1的话,直接跳过,不用考虑了,for(int j = 1; j <= m; j++) {if(r[j]) continue;//同上,这一列有1不考虑else {//否则将这一列标记上1,然后格子数量+1;sum++;r[j] = 1;break;}}}// cout << sum << endl;if(sum & 1) puts("Ashish");//判断答案奇偶即可。else puts("Vivek");}return 0;
}
Trouble Sort
思路
这题全靠瞎猜:分两种情况。
- 一、原本的数列就是有序的,这是肯定可以复原的到的。
- 二、原本的数列是无序的,所以我们必须进行交换,这个时候只有同时存在 0 ,1就行了。
赛后仔细想想好像确实是这样,假设只存在一个1,然后全是0,我们可以通过交换得到任意的排列。
代码
#include <bits/stdc++.h>using namespace std;typedef long long ll;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N = 510;int a[N], b[N], n;int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false);int t = read();while(t--) {n = read();int sum0 = 0, sum1 = 0;for(int i = 1; i <= n; i++) {a[i] = read();b[i] = a[i];}sort(a + 1, a + 1 + n);for(int i = 1; i <= n; i++) {int temp = read();if(temp) sum1++;else sum0++;}// for(int i = 1; i <= n; i++) // printf("%d%c", a[i], i == n ? '\n' : ' ');int flag = 1;for(int i = 1; i <= n; i++)//判断是否有序,if(a[i] != b[i]) {flag = 0;break;}if(flag) puts("Yes");//case 1else {//case 2if(sum1 && sum0) puts("Yes");else puts("No");}}return 0;
}
Rotation Matching
思路
首先我们明白,左移和右移的操作是等价的,任何通过左移得到的序列,我们都可以通过右移得到,反之亦然。所以我直接统计b序列的每个位置向右移动多少位可以得到在a中的相同位置,最后再统计一圈最大值就行了。
代码
#include <bits/stdc++.h>using namespace std;typedef long long ll;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N = 2e5 + 10;int a[N], b[N], sum[N], n;struct Node {int value, id;bool operator < (const Node & t) const {return value < t.value;}
}node[N];int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false);n = read();for(int i = 1; i <= n; i++) {node[i].value = read();node[i].id = i;}sort(node + 1, node + 1 + n);for(int i = 1; i <= n; i++) {a[i] = node[i].value;b[i] = read();}for(int i = 1; i <= n; i++) {int p = lower_bound(a + 1, a + 1 + n, b[i]) - a;p = node[p].id;//好像这里直接就可以是p = node[b[i]].id;,写比赛的时候傻了。// cout << p << endl;int len = p - i;if(len < 0) len += n;sum[len]++;}// for(int i = 0; i <= n; i++)// printf("%d%c", sum[i], i == n ? '\n' : ' ');int ans = 0;for(int i = 0; i <= n; i++)if(sum[i] > sum[ans])ans = i;printf("%d\n", sum[ans]);return 0;
}
Solve The Maze
思路
我们要保证最优,使所有的好人都可以到达n,mn, mn,m,所以我们一定要选择在每一个BBB的边上加墙,这个时候还有一点要注意,如果有好人是紧邻坏人的,那么我们一定不存在一种方案得到答案,这里直接在加墙的时候特判就行了。
加完墙之后,我们要保证所有的好人和n,mn, mn,m点是联通的,所以我们直接从n,mn, mn,m点开始dfs∣bfsdfs | bfsdfs∣bfs去访问所有可以达到的点,最后加一个特判,判断是否所有的好人和n,mn, mn,m是否联通,也就是看visit数组对应的点是否已经标记为1,然后这题就🆗了。
代码
#include <bits/stdc++.h>using namespace std;typedef long long ll;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}typedef pair<int, int> PII;
const int N = 55;
const int ax[4] = {1, 0, 0, -1}, ay[4] = {0, 1, -1, 0};char maze[N][N];
int visit[N][N];
int n, m;struct node{int x, y;node(int a = 0, int b = 0) : x(a), y(b) {}
};
queue<node> q;void bfs(int s,int t) {while(!q.empty()) q.pop();visit[s][t] = 1;q.push(node(s, t));while(!q.empty()) {node temp = q.front();q.pop();for(int i=0;i<4;i++) {int tempx = temp.x + ax[i];int tempy = temp.y + ay[i];if(maze[tempx][tempy] != '#' && visit[tempx][tempy] == 0) {visit[tempx][tempy] = 1;q.push(node(tempx, tempy));}}}
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false);int t = read();while(t--) {n = read(), m = read();for(int i = 1; i <= n; i++)scanf("%s", maze[i] + 1);for(int i = 0; i <= m + 1; i++)maze[0][i] = maze[n + 1][i] = '#';for(int i = 0; i <= n + 1; i++)maze[i][0] = maze[i][m + 1] = '#';int flag = 1;for(int i = 1; i <= n; i++) {for(int j = 1; j <= m; j++) {if(maze[i][j] == 'B') {// cout << i << " " << j << endl;int x = i, y = j;for(int k = 0; k < 4; k++) {if(maze[x + ax[k]][y + ay[k]] == 'G') {//这个点一定要注意特判,不然直接wa,flag = 0;break;}if(maze[x + ax[k]][y + ay[k]] == '.')maze[x + ax[k]][y + ay[k]] = '#';}}if(!flag) break;}if(!flag) break;}memset(visit, 0, sizeof visit);if(maze[n][m] != '#') bfs(n, m);for(int i = 1; i <= n;i++) {for(int j = 1; j <= m; j++) {if(maze[i][j] == 'G') {if(visit[i][j]) continue;else {flag=0;break;}}if(!flag) break;}if(!flag) break;}if(flag) puts("Yes");else puts("No");}return 0;
}