POJ 2612/ZOJ 1862 Mine Sweeper

题目链接:

http://poj.org/problem?id=2612

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1862

题目描述:

扫雷游戏是在n×n的网格内进行的,其中藏有m颗地雷,这些地雷分布在不同的位置。游戏者不停地点开网格中的位置。如果点开了地雷,则引爆地雷,游戏失败。如果点开了没有地雷的位置,则显示一个0~8之内的整数,表示这个位置的8个相邻位置中藏有地雷的位置的数目。

下图中,n为8,m为10。图中空白的位置代表整数0,凸起的位置表示还没点开,类似于“*”号的符号代表地雷。最左边的图表示点开了部分位置。从第1幅图到第2幅图,游戏者已经点开了2个位置,都没有点到地雷;但在第3幅图中,游戏者就没那么幸运了,他点中了藏有地雷的位置,游戏失败。如果游戏者将所有没有地雷的位置都点开,只有m个藏有地雷的位置没点开,则游戏成功。

                        

                 

你的任务是读入玩了一部分的游戏信息,输出对应的游戏地图

输入描述:

输入文件包含了多个测试数据。每个测试数据的第1行为一个正整数n,n≤10,表示该扫雷游戏的地图是n×n大小的。接下来n行描绘了地雷的位置。每一行有n个字符:“.”表示没有地雷的位置,“*”号表示地雷的位置。接下来又是n,每行n个字符:已经点开的位置用字符“X”表示,没有点开的位置用字符“.”表示。样例输入对应到上图中中间那幅图。

输入数据一直到文件尾。

输出描述:

对每个测试数据,输出对应的地图,每个位置都用正确的符号填充已经点开并且没有地雷的位置用0~8之内的整数表示。注意,如果某个位置藏有地雷且被点开了,则所有地雷的位置都用“*”号表示对没有点开的其他位置都用“.”表示。

每两个测试数据对应的输出之间有一个空行。

分析:

这是一道很有意思的题目,模拟的是扫雷游戏。输入的是标明地雷位置的地图,及游戏者已经点开的位置,要求输出显示给游戏者看的地图

首先要根据输入的地图,统计每个位置的8个相邻位置上地雷的数目,可以设计一函数来实现。对位置(i,j)来说,它的8个相邻位置从左上角位置开始按顺时针顺序依次为:(i-1,j-1)、(i-1,j)、(i-1,j+1)、(i,j+1)、(i+1,j+1)、(i+1,j)、(i+1,j-1)、(i,j-1)。但在本题中,并非需要统计所有位置,只需要统计已点开过且没有地雷的位置。在统计过程中,即可判断是否引爆了地雷

然后要根据统计的结果输出显示给游戏者看的地图:如果没有引爆了地雷,则点开过的位置显示其周围8个位置上地雷总数,未点开的位置显示“.”;如果引爆了地雷,则所有地雷都输出"*"号,其他位置的处理跟没有引爆地雷时的处理是一样。

注意,本题要求在两个测试数据之间输出空行,言下之意就是除最后一个测试数据的输出外,每个测试数据的输出之后有一个空行。如果在每个测试数据的输出之后都输出一个空行,得到的评判结果是格式错误。

代码:

#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char str1[13][13];
char str2[13][13];
int n;
int gg(int i,int j)
{
    int count=0;
   for(int dx=-1;dx<=1;dx++)
        for(int dy=-1;dy<=1;dy++)
        if( dx+i<n && dx+i>=0 &&dy+j<n && dy+j>=0 && str1[dx+i][dy+j]=='*')
            count++;

	return count;


}
int main()
{
    int number=1;

    while(scanf("%d",&n)!=EOF)
    {
        if(number!=1)
            printf("\n");
        number++;
        bool flag1=true;
        for(int i=0;i<n;i++)
            {
                scanf("%s",str1[i]);

            }
        for(int i=0;i<n;i++)
            {

                scanf("%s",str2[i]);

            }
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
            {
                if(str2[i][j]=='x' && str1[i][j]=='*')
                  flag1=false;
            }
            if(flag1)
            {
                for(int i=0;i<n;i++)
                  {
                      for(int j=0;j<n;j++)
                     {
                         if(str2[i][j]=='x')
                            printf("%d",gg(i,j));
                         else
                         printf(".");

                     }
                     printf("\n");
                  }

            }
            else
            {
               for(int i=0;i<n;i++)
             {

                 for(int j=0;j<n;j++)
                 {
                   if(str2[i][j]=='x' && str1[i][j]!='*')
                    printf("%d",gg(i,j));
                   if(str1[i][j]=='*' )
                    printf("*");
                    if(str2[i][j]=='.' && str1[i][j]!='*')
                        printf(".");
                 }
                 printf("\n");
             }
            }
    }
    return 0;
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值