基础算法_扫雷的思维题

题意:

给两个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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我会尽力回答你的问。关于扫雷游戏的布算法、策略与优化,其实是一个比较复杂的话,需要涉及到一些数学、算法和编程知识。不过我会尽量用简单的语言来介绍。 首先,扫雷游戏的布算法是指在游戏开始前,计算机如何随机生成一个扫雷地图。一般来说,扫雷地图会被分成若干个小格子,每个格子要么是,要么是数字数字代表周围八个格子中有多少个。布算法的目标就是随机分布数字,让游戏变得有趣和有挑战性。 一个简单的布算法是随机生成若干个的位置,然后计算每个数字格子周围的数。这种算法的缺点是可能会出现非常简单或非常困难的地图,而且的数量可能不够平均分布。为了解决这个问,可以采用更高级的算法,比如基于概率的布算法或者优化的布算法。 基于概率的布算法是指按照一定的概率分布来生成数字。比如,可以先随机生成一些数字格子,然后根据周围数字格子的个数来计算生成的概率。这样可以保证的数量比较平均分布,但是仍然存在一些不合理的地图。 优化的布算法是指结合了各种启发式算法和优化算法来生成地图,比如遗传算法、模拟退火算法、粒子群算法等。这些算法可以保证生成的地图比较合理和有挑战性,但是计算复杂度较高,需要较强的计算能力。 至于扫雷游戏的策略和优化,也有很多研究。一般来说,扫雷游戏的策略分为两种:基于推理的策略和基于直觉的策略。基于推理的策略是指根据已知的数字格子,推理出未知的格子还是数字。这种策略需要一定的逻辑和推理能力,可以通过编写算法自动实现。基于直觉的策略是指根据已知的局面和经验,直觉地猜测未知的格子还是数字。这种策略需要一定的经验和感觉,很难通过编写算法来实现。 在实现扫雷游戏的算法时,可以使用Python这样的高级编程语言来实现。以下是一个简单的Python实现扫雷游戏的代码,供参考: ```python import random class MineSweeper: def __init__(self, width=10, height=10, mines=10): self.width = width self.height = height self.mines = mines self.grid = [[0 for y in range(height)] for x in range(width)] self.revealed = [[False for y in range(height)] for x in range(width)] self.flagged = [[False for y in range(height)] for x in range(width)] self.generate_grid() def generate_grid(self): positions = [(x, y) for x in range(self.width) for y in range(self.height)] random.shuffle(positions) mine_positions = positions[:self.mines] for x, y in mine_positions: self.grid[x][y] = -1 for dx in [-1, 0, 1]: for dy in [-1, 0, 1]: if x+dx >= 0 and x+dx < self.width and y+dy >= 0 and y+dy < self.height and self.grid[x+dx][y+dy] != -1: self.grid[x+dx][y+dy] += 1 def reveal(self, x, y): if self.grid[x][y] == -1: return False self.revealed[x][y] = True if self.grid[x][y] == 0: for dx in [-1, 0, 1]: for dy in [-1, 0, 1]: if x+dx >= 0 and x+dx < self.width and y+dy >= 0 and y+dy < self.height and not self.revealed[x+dx][y+dy]: self.reveal(x+dx, y+dy) return True def flag(self, x, y): self.flagged[x][y] = not self.flagged[x][y] def game_over(self): for x in range(self.width): for y in range(self.height): if self.grid[x][y] == -1 and self.revealed[x][y]: return True return False def game_won(self): for x in range(self.width): for y in range(self.height): if self.grid[x][y] != -1 and not self.revealed[x][y]: return False return True def print_grid(self): for y in range(self.height): for x in range(self.width): if self.revealed[x][y]: if self.grid[x][y] == -1: print("*", end="") else: print(self.grid[x][y], end="") elif self.flagged[x][y]: print("F", end="") else: print(".", end="") print() ``` 这段代码实现了一个简单的扫雷游戏,包括布算法、揭示格子、标记格子、游戏结束和游戏胜利的判断,以及输出游戏地图的功能。你可以根据自己的需要来调整参数和改进算法。 希望这个回答能够帮到你。如果你还有其他问,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值