1006: Mine Sweeper(扫雷)


这大概是很多童鞋第一次玩的经典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<<"*";
				else
					cout<<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个 。。。 下次得注意···

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值