链接:https://ac.nowcoder.com/acm/contest/9925/B
题目大意
给你2个n×m扫雷图A、B,图中没有雷的格子会有一个数字x,表示这个格子周围9×9的格子中有多少个雷。现在你可以最多修改B图$\frac {nm}2$次来使得两个图中的数字之和相等,输出修改后的B图。
分析
考虑数字和就等于相邻(雷格子,非雷格子)二元组的个数,于是把整个地图全反过来这个二元组个数不变,然后 $B$ 与 $A$之间以及 $B$ 与 $inv(A)$ ,即把 $A$ 所有格子全部取反的扫雷地图之间总有一个偏差不超过一半的,所以就选其中偏差不超过一半的然后变过去就行。
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include <bits/stdc++.h> using namespace std; const int N = 1000 + 5; int ga[N][N], gb[N][N]; int n, m, cntOri, cntInv;
void print() { for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) printf("%c", gb[i][j] ? 'X' : '.'); printf("\n"); }
}
int main() { cin >> n >> m; char ch; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { scanf(" %c", &ch); ga[i][j] = ch == 'X' ? 1 : 0; }
for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { scanf(" %c", &ch); gb[i][j] = ch == 'X' ? 1 : 0; }
for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { cntOri += ga[i][j] ^ gb[i][j] ^ 1 ; cntInv += ga[i][j] ^ gb[i][j]; }
int f = cntOri > cntInv ? 0 : 1; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { gb[i][j] = ga[i][j] ^ f; } print(); }
|