题意:
给两个n * m的扫雷游戏的图a和b,那我们要做的是什么呢?是这样的qaq,如果一个格子里没有雷,那么这里会有一个数字,这个数字的值等于当前没有雷的格子周围八个方向的雷的数量
现在可以对b操作最多⌊ nm/2⌋次
每次操作可以将有雷的格子换成没有雷的格子,也可以将没有雷的格子换成有雷的格子
问把b换成什么样子的图,能使a和b没有雷的格子的数字之和相等。。。如果没有办法实现,就输出-1
输入:
n和m
a图和b图
输出:
转换后的b图
输入
2 4
X…X
X.X.
X.X.
.X…
输出
X.XX
.X…
说明
We modify one cell in B. Then the sums of the numbers on non-mine cells in A and B both equal 10.
思路:
官方题解是这个亚子的
考虑数字和就等于相邻(雷格子,非雷格子)二元组的个数,于是把整个地图全反过来这个二元组个数不变,然后 A 与 B之间以及 A与 inv(B) ,即把 A所有格子全部取反的扫雷地图之间总有一个偏差不超过一半的,所以就选其中偏差不超过一半的然后变过去就行。
很清楚了,关键就是(雷格子,非雷格子)二元组的个数,在A的每个字符反转之后不变
代码实现:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 3e6 + 5;
char a[1005][1005];
char b[1005][1005];
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++){
scanf(" %s",a[i] + 1);
}
for(int i = 1;i <= n;i++){
scanf(" %s",b[i] + 1);
}
/*
把条件放宽到n * m / 2 向下取整,其实就应该往大的方面考虑了
主要是利用a的每个字符反转前后,(空白格,雷格)的二元组的数量不变
*/
int tmp = 0;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
if(a[i][j] != b[i][j]) tmp++;
}
}
if(tmp <= (n * m) / 2){
for(int i = 1;i <= n;i++){
printf("%s\n",a[i] + 1);
}
}
else{
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
if(a[i][j] == '.') printf("X");
else printf(".");
}
printf("\n");
}
}
return 0;
}