题意:
给定两个扫雷n*m的矩阵A和B
在进行最多 f l o o r ( n ∗ m / 2 ) floor(n*m/2) floor(n∗m/2)次取反操作之后,把B中的所有非地雷格子的数字的和等于A中的值
(非地雷格子中的数字表示在以自己为中心的3x3的格子中有多少个地雷)
求出任意符合题意的翻转方案
思路
看到 f l o o r ( n ∗ m / 2 ) floor(n*m/2) floor(n∗m/2)次操作,想到取反
易证得,一个矩阵翻转后数字和不变
翻转后总有一个操作不超过 f l o o r ( n ∗ m / 2 ) floor(n*m/2) floor(n∗m/2)次
直接输出原来的A或者翻转后A即可
代码
Time:12ms
Memory:3368kb
#include<cstdio>
#include<algorithm>
using namespace std;
bool A[1005][1005],B[1005][1005];
char s[1005];
int n, m;
void output() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
printf("%c", A[i][j] ? 'X' : '.');
}
printf("\n");
}
return;
}
int main(void) {
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) {
scanf("%s", s);
for (int j = 0; j < m; j++) {
A[i][j] = s[j] == 'X';
}
}
for (int i = 0; i < n; i++) {
scanf("%s", s);
for (int j = 0; j < m; j++) {
B[i][j] = s[j] == 'X';
}
}
int cnt = 0;
int lim = n * m / 2;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cnt += A[i][j] ^ B[i][j];
}
}
if (cnt > lim) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
A[i][j] ^=1;
}
}
}
output();
return 0;
}