Uva Problem 10189 Minesweeper Problem

本文介绍了一种使用字符数组表示地雷图并逐个扫描统计各点周围地雷总数的方法。通过设定边界数组来确定每个点周围的八个相邻点,进而统计这些点中地雷的数量。适用于初学者理解扫雷游戏的基本算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Have you ever played Minesweeper? This cute little game comes with a certain operating system whose name we can’t remember. The goal of the game is to find where all the mines are located within a M × N field.
The game shows a number in a square which tells you how many mines there are adjacent to that square. Each square has at most eight adjacent squares. The 4×4 field on the left contains two mines, each represented by a “*” character. If we represent the same field by the hint numbers described above, we end up with the field on the right:
*...
....
.*..
....
*100
2210
1*10
1110
Input
The input will consist of an arbitrary number of fields. The first line of each field contains two integers n and m (0 < n,m ≤ 100) which stand for the number of lines and columns of the field, respectively. Each of the next n lines contains exactly m characters, representing the field.
Safe squares are denoted by “.” and mine squares by “*,” both without the quotes. The first field line where n = m = 0 represents the end of input and should not be processed.
Output
For each field, print the message Field #x: on a line alone, where x stands for the number of the field starting from 1. The next n lines should contain the field with the “.” characters replaced by the number of mines adjacent to that square. There must be an empty line between field outputs.
Sample Input
4 4
*...
....
.*..
....
3 5
**...
.....
.*...
0 0
Sample Output
Field #1:
*100
2210
1*10
1110
Field #2:
**100
33200

1*100

解题方法转自:http://blog.youkuaiyun.com/metaphysis/article/details/6432031

// Minesweeper (扫雷)  
// PC/UVa IDs: 110102/10189, Popularity: A, Success rate: high Level: 1  
// Verdict: Accepted   
// Submission Date: 2011-04-09  
// UVa Run Time: 0.012s  
//  
// 版权所有(C)2011,邱秋。metaphysis # yeah dot net  
//  
// 解题思路很简单,使用字符数组表示给定的地雷图,逐个扫描统计各点周围的地雷总数。在计算地雷总数时,  
// 用到了一个小技巧,设置边界数组 bounds,将当前的点顺次加上边界数组的值即可得到当前点周围的 8 个  
// 点,注意不要忘记判断点是否在地雷地图范围内。  

#include <iostream>  
#include <cstring>  

using namespace std;  

#define MAXSIZE 100  

inline bool range_checking(int x, int y, int line, int row)  
{  
	return (0 <= x && x < line) && (0 <= y && y < row);  
}  

void display(char matrix[][MAXSIZE], int line, int row)  
{  
	int bounds[8][2] =  
	{ {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0},  
	{1, 1} };  

	for (int i = 0; i < line; i++)  
	{  
		for (int j = 0; j < row; j++)  
		{  
			// 如果该位置为地雷则原样输出地雷的符号。  
			if (matrix[i][j] == '*')  
				cout << "*";  
			else  
			{  
				// 统计该点周围 8 点的地雷总数。  
				int mines = 0;  
				for (int k = 0; k < 8; k++)  
				{  
					/*
						将二维数组想象成为XY轴,
						先求X坐标,然后求Y坐标
					*/
					int m = i + bounds[k][0];  
					int n = j + bounds[k][1];  
					/*
						首先判断这个点是否在地雷地图范围内
						其次判断是否有雷
					*/
					if (range_checking(m, n, line, row)  
						&& matrix[m][n] == '*')  
						mines++;  
				}  

				cout << mines;  
			}  
		}  

		cout << endl;  
	}  
}  

int main(int ac, char *av[])  
{  
	char matrix[MAXSIZE][MAXSIZE];  
	int line, row, field = 0;  

	while ((cin >> line >> row, line && row))  
	{  
		memset(matrix, 0, sizeof(matrix));  

		for (int i = 0; i < line; i++)  
			for (int j = 0; j < row; j++)  
				cin >> matrix[i][j];  

		if (field > 0)  
			cout << endl;  
		field++;  

		cout << "Field #" << field << ":" << endl;  

		display(matrix, line, row);  
	}  

	return 0;  
}  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值