L - Left Mouse Button (DFS)

Mine sweeper is a very popular small game in Windows operating system. The object of the game is to find mines, and mark them out. You mark them by clicking your right mouse button. Then you will place a little flag where you think the mine is. You click your left mouse button to claim a square as not being a mine. If this square is really a mine, it explodes, and you lose. Otherwise, there are two cases. In the first case, a little colored numbers, ranging from 1 to 8, will display on the corresponding square. The number tells you how many mines are adjacent to the square. For example, if you left-clicked a square, and a little 8 appeared, then you would know that this square is surrounded by 8 mines, all 8 of its adjacent squares are mines. In the second case, when you left-click a square whose all adjacent squares are not mines, then all its adjacent squares (8 of its adjacent squares) are mine-free. If some of these adjacent squares also come to the second case, then such deduce can go on. In fact, the computer will help you to finish such deduce process and left-click all mine-free squares in the process. The object of the game is to uncover all of the non-mine squares, without exploding any actual mines. Tom is very interesting in this game. Unfortunately his right mouse button is broken, so he could only use his left mouse button. In order to avoid damage his mouse, he would like to use the minimum number of left clicks to finish mine sweeper. Given the current situation of the mine sweeper, your task is to calculate the minimum number of left clicks.

                                                                         

Input

The first line of the input contains an integer T (T <= 12), indicating the number of cases. Each case begins with a line containing an integer n (5 <= n <= 9), the size of the mine sweeper is n×n. Each of the following n lines contains n characters M ij(1 <= i,j <= n), M ij denotes the status of the square in row i and column j, where ‘@’ denotes mine, ‘0-8’ denotes the number of mines adjacent to the square, specially ‘0’ denotes there are no mines adjacent to the square. We guarantee that the situation of the mine sweeper is valid.

Output

For each test case, print a line containing the test case number (beginning with 1) and the minimum left mouse button clicks to finish the game.

Sample Input

1
9
001@11@10
001111110
001111110
001@22@10
0012@2110
221222011
@@11@112@
2211111@2
000000111

Sample Output

Case 1: 24

 

【解析】

題意:掃雷,點擊任意一個0,則任何與之相連通的0和與0最近的一層都會被翻開。都會被翻開,數字表示該位置周圍八個方向共有多少地雷,@表示地雷。問最少需要點擊幾次才能贏得這局掃雷。

很明顯就是深搜的題目了。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 100;
int vis[maxn][maxn], n;
char gra[maxn][maxn];
const int dir[10][2] =
{
	{ 0,1 },{ 0,-1 },{ 1,0 },{ -1,0 },//行
	{ 1,-1 },{ 1,1 },{ -1,-1 },{ -1,1 }//列
};

void dfs(int x, int y)
{
	vis[x][y] = 1;//此處先標記訪問過,目的就是對0周圍的一圈也翻開。
	if (gra[x][y] != '0')return;
	for (int i = 0; i < 8; i++)
	{
		int r = x + dir[i][0], c = y + dir[i][1];
		if (r < 0 || r >= n)continue;//超出掃雷範圍
		if (c < 0 || c >= n)continue;
		if (!vis[r][c])//如果未曾被訪問過,則下一層遞歸
			dfs(r, c);
	}
}
int main()
{
	int T;
	scanf("%d", &T);
	for (int i = 1; i <= T; i++)
	{
		scanf("%d", &n);
		for (int i = 0; i < n; i++)
			scanf("%s", gra[i]);
		memset(vis, 0, sizeof(vis));

		int ans = 0;
		for (int i = 0; i < n; i++)//0時連通
		{
			for (int j = 0; j < n; j++)
			{
				if (!vis[i][j] && gra[i][j] == '0')
				{
					dfs(i, j);
					ans++;
				}
			}
		}
		for (int i = 0; i < n; i++)//不是地雷
		{
			for (int j = 0; j < n; j++)
			{
				if (!vis[i][j] && gra[i][j] != '@')
					ans++;
			}
		}

		printf("Case %d: %d\n", i, ans);
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章