Problem M: 扫雷
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 27 Solved: 21
[Submit][Status][Web Board]
Description
Windows 中的扫雷游戏是大家都熟悉的小游戏,今天,味味也设计了一个简易的扫雷游戏。味味设计的扫雷游戏功能如下:
1.程序一开始会读入扫雷区域大小 n,表示游戏区域有 n*n 个小方格组成,接下来会读入 n 行信息,每行有 n 个整数(每个整数可能是 0,也可能是 1),每两个整数之间用一个空格分隔。其中 0 所在位置表示该小方格内没有地雷,1 所在位置表示该小方格内有地雷(游戏开始时,扫雷区域 中必定包含至少一个地雷)。
接下来每行输入两个用空格分开的正整数 i 和 j,每一行的一对 i 和 j 表示用户用鼠标单击扫 雷区域中第 i 行第 j 列位置上的小方格(就象我们使用 Windows 中扫雷游戏一样),i 和 j 表示的 位置必定在扫雷区域内。程序每输入一对 i 和 j,就马上进行相应的处理(就象我们在 Windows 中 鼠标单击某个小方块就会出现结果一样)。
2.程序将根据读入的一组 i 和 j 的值来对扫雷区域作相应处理,具体的处理规则如下:
(1)如果 i 和 j 表示的小方格内没有地雷、而且也没有被处理过(就是第 i 行第 j 列的数值 是 0),那么将以该小方格为中心的一个正方形区域内所有没有地雷的小方格都赋值为-1(表示该 区域的地砖已经被掀开了)。如果在当前正方形区域内有一个位置号为 i1 和 j1(注意:i1<>i 并且 j1<>j)的小方格内恰好有地雷,则此地雷就被顺利扫除,将该位置标记为-2。如果该正方形区域 内某些小方格已经被处理过,则对这些小方格不再做任何处理。
举个例子来说明一下,假如输入信息如下左边所示,那么处理结果就如下右边所示:
(2)如果 i 和 j 表示的小方格已经被处理过(就是第 i 行第 j 列的数值是-1 或者是-2),那 么不作任何处理,继续去读取下一行的 i 和 j 的值。
(3)如果 i 和 j 表示的小方格刚好有地雷,并且该小方格没有被处理过(就是第 i 行第 j 列 的数值是 1),那么表示用户触雷,马上输出信息“GAME OVER!”,程序结束。
3.如果在读入 i 和 j 的过程中一直没有触雷,那么就一直按照位置信息处理下去,直到满足下 列条件之一,就输出相应信息并结束程序:
(1)读入的 i 和 j 的值都是 0(表示用户不再在某个小方格内单击鼠标右键了),则输出处理 后整个扫雷区域的状态(就是输出 n 行 n 列的方阵,每行中两个整数之间用一个空格分隔,末尾没 有多余空格),然后程序结束。
(2)如果某次处理完后,游戏区域内所有的地雷都被扫除了,那么不必再读入下一行的信息, 输出信息“YOU ARE WINNER!”,程序结束。
Input
第一行一个整数 n(n<=50),接下来是一个 n*n 的方阵。再接下来是若干行,每行空格分隔的两个整数,表示 i 和 j,以 0 0 结束。
Output
包含一行,可能输出“YOU ARE WINNER!”,可能输出“GAME OVER!”, 也可能输出一个处理后的方阵。
Sample Input
6
0 0 0 0 0 0
0 0 1 0 0 0
1 0 0 0 1 0
0 0 0 0 0 0
0 1 0 0 0 1
0 0 0 0 0 0
1 1
3 4
5 5
4 6
5 2
2 3
0 0
6
0 0 0 0 0 0
0 0 1 0 0 0
1 0 0 0 1 0
0 0 0 0 0 0
0 1 0 0 0 1
0 0 0 0 0 0
1 1
3 4
5 5
4 6
2 3
0 0
Sample Output
GAME OVER!
-1 -1 0 0 0 0
-1 -1 -2 -1 -1 0
1 0 -1 -1 -2 0
0 0 -1 -1 -1 -1
0 1 0 -1 -1 -2
0 0 0 -1 -1 -1
HINT
显然是个深搜题,这里用数组模拟队列。
#include<cstdio>
using namespace std;
int x,y,n,map[51][51];
int dx[9]={0,-1,-1,-1,0,0,1,1,1};
int dy[9]={0,-1,0,1,-1,1,-1,0,1};
bool judge()
{
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (map[i][j]>0) return 0;
return 1;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
scanf("%d",&map[i][j]);
while (scanf("%d %d",&x,&y)==2)
{
if (map[x][y]==1) //判断游戏是否结束,即踩到地雷
{
printf("GAME OVER!");
return 0;
}
if (!x&&!y) //判断数据是否输完
{
for (int i=1;i<=n;i++) //打印
{
printf("%d",map[i][1]); //为了防止多打空格,不然PE
for (int j=2;j<=n;j++)
printf(" %d",map[i][j]);
printf("\n");
}
return 0;
}
else if (map[x][y]>=0) //判断是否未处理
for (int i=0;i<9;i++) //循环每种处理情况
{
int tx=x+dx[i],ty=y+dy[i]; //处理
if (tx>0&&ty>0&&tx<=n&&ty<=n&&map[tx][ty]>=0) //判断被影响的区域是否也未被处理
{
if (!map[tx][ty]) map[tx][ty]=-1; //若不是地雷,处理
else map[tx][ty]=-2; // 若为地雷,扫雷成功
}
}
if (judge()) //判断是否都被处理过
{
printf("YOU ARE WINNER!"); //真的扫雷成功啦
return 0;
}
}
return 0;
}