0%

2020ICPC(上海)-Mine Sweeper II

链接: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();
}

欢迎关注我的其它发布渠道