B-Mine Sweeper II

2020 ICPC 上海站 B
原题链接:https://ac.nowcoder.com/acm/contest/10330/B
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
题意
给你两个大小为 n * m 的扫雷图 A, B,要求通过最多 n * m/2 次转换(转换指 把一个不是雷的格子变成雷, 或者把一个是雷的格子变成空白格),使得 B图的值 和 A图的值相等(值 就是指 扫雷图上的所有数字之和,没有数字或者雷的地方的值为0)

思路
其实这道题,只要相通一件事情,就可以了。
(一个地雷对于他对他周围的空白格的影响) 等价于 (把他周围的空白格都变成雷,自己变成空白格的的影响),也就是说,这个把这个图置反(雷变空白,空白变雷),和原图其实是一样的。且题目说,最多可以进行 mn/2 次转换操作,那么B图必然可以转化成A图或A的反(这个应该称为补图吧),也就是说,不存在 -1 的情况,所以只要把补图求出来,然后看看 A 或者 A的补图 哪个转换成B的次数小于 nm/2, 那个图就行了,可能讲的不是很清楚,见谅

AC代码

#include <bits/stdc++.h>
using namespace std;
#define maxn 1005

char G[maxn][maxn];// 图A
char G2[maxn][maxn];// 图A 的 补图
char K[maxn][maxn];// 图B
int n, m;

int main(){
    
    
	scanf("%d %d", &n, &m);
	for(int i=1;i<=n;++i) scanf("%s", G[i]+1);
	for(int i=1;i<=n;++i) scanf("%s", K[i]+1);
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j)
			G2[i][j]=(G[i][j]=='.'?'X':'.'); // 求图A 的 补图
	int cnt=0, cnt2=0; //分别用来记录 把图A 转换 成图B 和 把图A的补图 转换成B 所需的转换次数
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j)
			if(G[i][j]^K[i][j]) cnt++;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j)
			if(G2[i][j]^K[i][j]) cnt2++;
	if(cnt<=n*m/2){
    
    //只要 转换次数符合条件 就输出
		for(int i=1;i<=n;++i) printf("%s\n", G[i]+1);
	}
	else{
    
    
		for(int i=1;i<=n;++i) printf("%s\n", G2[i]+1);
	}

	return 0;
}```

猜你喜欢

转载自blog.csdn.net/qq_45757639/article/details/111395644