1006: Mine Sweeper(扫雷)

来源:互联网 发布:unity3d播放声音 编辑:程序博客网 时间:2024/05/19 21:19


这大概是很多童鞋第一次玩的经典PC游戏了。翻译如下(练习英语):

原题链接:http://acm.nankai.edu.cn/p1006.html

扫雷游戏在一个n x n 的网格上进行,在这些格子中隐藏着m个地雷,且每一个都在不同个格子里。玩家不断的点击格子,如果点击的格子埋有地雷,地雷爆炸同时玩家游戏失败。如果点击的格子没有地雷,一个属于[0,8]的数字出现,指示出这个格子相邻或对角(diagonally )相邻的共8个格子中一共包含多少地雷。下面是一些游戏的截图:

  

这里, n=8, m=10,正方型代表整数0 ,凸起的正方形表示没有点开的格子,星号代表地雷,最左边的图片展示了一个进行了一部分的游戏,从左边第一张到第二张,玩家进行了两次点击,每一次都选择了一个安全的格子。从第二张到第三张,玩家就不那么幸运了;他选择了一个埋有地雷的格子,因此输掉了游戏,玩家玩家继续点击安全的地方,直到10个地雷都被发现,那玩家就赢了。你的任务是读取部分进行的游戏场景并打印出相应的游戏状态。


输入

第一行包含单个正整数 n<=10 ,以下n行描绘出地雷的位置,每一行用n个字符表示出游戏地图的一行,点代表没有埋地雷的格子,星号代表地雷。再往下n行都有n个字符长,

已经点击过的格子用'x'表示,未点击的格子用'.'表示,以下的输入示例正好指示出上面中间图片的游戏状态。


输出

你的输出必须指示出合适的游戏状态:1.已经被点击的格子如果没有埋有地雷,必须包含一个[0-8]的整数;2.如果有地雷被点击了,所有包含地雷的格子必须用‘*’表示,其他的格子用'.'表示。


示例输入

8
...**..*
......*.
....*...
........
........
.....*..
...**.*.
.....*..
xxx.....
xxxx....
xxxx....
xxxxx...
xxxxx...
xxxxx...
xxx.....
xxxxx...

示例输出

001.....
0013....
0001....
00011...
00001...
00123...
001.....
00123...

提示

15个测试用例。


朴素解法,遍历,计算,OOpp

#include<iostream>#include<string.h>using namespace std;#define SAFE  '.'#define MINE'*'#define TOUCH'x'typedef struct{int x;int y;}position_t;position_t pos[8];#define POSTION_VALID(x, y, n)    (x)>=0 && (y)>=0 && (x)<(n) && (y)<(n) void calulate(int i,int j){pos[0].x=i-1;pos[0].y=j-1;pos[1].x=i;pos[1].y=j-1;pos[2].x=i-1;pos[2].y=j;pos[3].x=i+1;pos[3].y=j+1;pos[4].x=i+1;pos[4].y=j;pos[5].x=i;pos[5].y=j+1;pos[6].x=i-1;pos[6].y=j+1;pos[7].x=i+1;pos[7].y=j-1;}int main(){int n;char str[11]; while( cin >>n ){if( n <0 || n > 10 )break;char **mine=new char*[n];char **touch=new char*[n];char **result=new char*[n];for(int i=0;i<n;i++){mine[i]=new char[n];touch[i]=new char[n];result[i]=new char[n];}char **output=result;for(int i=0;i<n;i++){cin >> str;memcpy( mine[i] , str, n );}for(int i=0;i<n;i++){cin >> str;memcpy( touch[i] , str, n );}int bose=0;for(int i=0;i<n;i++){for(int j=0;j<n;j++){if( touch[i][j]!= TOUCH ){result[i][j]='.';}else if( touch[i][j]==TOUCH && mine[i][j]==MINE){bose=1;}else if( touch[i][j]==TOUCH && mine[i][j]==SAFE   ){int count=0;calulate(i,j);for(int k=0;k<8;k++){if( POSTION_VALID( pos[k].x,pos[k].y ,n) ){if(mine[ pos[k].x ] [ pos[k].y ] == MINE )count++;}}result[i][j]=count+'0';}}} for(int i=0;i<n;i++){for(int j=0;j<n;j++){if( bose==1 && mine[i][j]==MINE )cout<<"*";elsecout<<output[i][j];}cout<<endl;}for(int i=0;i<n;i++){delete [] mine[i];delete [] touch[i]; delete [] result[i]; }delete [] mine;delete [] touch;delete [] result;}}

以上代码似乎不太美观,但是可以AC。编码过程中引入一个问题?

在C++如何用new创建多维数组???

//错误代码 1

char **a=new char[10][10];

//错误代码 2

int n=10;

char (*a)[n];

a=new char[n][m];


正确代码:

char **array=new char*[n];
for(int i=0;i<n;i++)
    array[i]=new char[m];


由于读题不仔细造成贡献WA n个 。。。 下次得注意···

原创粉丝点击