Mine Number(2012年"浪潮杯"山东省第三届ACM大学生程序设计竞赛)

Mine Number

Time Limit: 1000ms   Memory limit: 65536K

题目描述

Every one once played the game called Mine Sweeping, here I change the rule. You are given an n*m map, every element is a '*' representing a mine, or a '.' representing any other thing. If I ask you what's the total number of mines around (i, j), you should check (i, j)'s up, down, left, right and also itself (if overstep the boundary, ignore it), if that position is a '*', you should add one to the total number of (i, j), and here I call the number Mine Number. For example, if the map is "..**.. ", we can get the Mine Number as "012210" easily, but here is the question, if I give you the Mine Number, can you tell me the original map?

输入

The input consists of multiple test cases.
The first line contains a number T, representing the number of test cases.
Then T lines follow. For each case, the first line contains two numbers n and m (1<=n, m<=20).representing the lines and rows. Then following n lines, each line contain m numbers each number represents the Mine Number.

输出

For each case, please print the case number (beginning with 1) and the original map which you reverted. The data guarantee there is only one result.

示例输入

2
7 11
10010100101
21223221222
32354532323
32355532323
31235321333
21022201333
10001000111
5 6
001110
013431
014541
013431
001110

示例输出

Case 1:
...........
*..*.*..*.*
*.*****.*.*
*.*****.*.*
*..***..*.*
*...*...***
...........
Case 2:
......
..***.
..***.
..***.
......
搜索问题(DFS)
题意:每一位置的数字代表上下左右中五个位置的地雷数,将数字图转换成符号图输出。
思路:每一位置只有.和*两种可能,从map[1][1]开始放置放到map[n][m],其中通过对map[i][j-1]和map[i-1][j]地雷数检测进行剪枝
#include<iostream>
#include<string.h>
using namespace std;
int m,n,X;
int s[5][2]={1,0,-1,0,0,1,0,-1,0,0};//五个方向,上下左右中
int f[22][22];
char map[22][22];
int check2(char map[22][22])//检查全图是否符合要求
{
	int check(int,int,char map[22][22]);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(check(i,j,map)!=f[i][j]) return 0;
			return 1;
}
int check(int i,int j,char map[22][22])//map[i][j]位置周围地雷数
{
	int a=0,z;
	for(z=0;z<5;z++)
		if(i+s[z][0]>0&&i+s[z][0]<=n&&j+s[z][1]>0&&j+s[z][1]<=m)
		{
			if(map[i+s[z][0]][j+s[z][1]]=='*') a++;
		}
		return a;
}

int DFS(int i,int j,char map[22][22])//搜索
{
	int z,y;
	if(X==1) return 0;//X=1标记已输出地图
	if(check2(map))
	{
		X=1;
		for(z=1;z<=n;z++)
		{
			for(y=1;y<=m;y++)
				cout<<map[z][y];
			cout<<endl;
		}
		return 0;
	}
	if(i==n&&j==m+1) return 0;//地图放置完毕
	if(i==1&&j>1)//检测map[i][j-1]位置
		if(check(i,j-1,map)>f[i][j-1]) return 0;
	if(j<m&&i<=n||i==n&&j==m)//继续在该行放置
	{
		map[i][j]='.';
        if(i==1||check(i-1,j,map)==f[i-1][j])//检测map[i-1][j]是否成立
		DFS(i,j+1,map);
       
		map[i][j]='*'; 
		if(i==1||check(i-1,j,map)==f[i-1][j])
		DFS(i,j+1,map);
		map[i][j]='.';
	}
	else if(j==m&&i<n)//到下一行放置
	{
		map[i][j]='.';
        if(i==1||check(i-1,j,map)==f[i-1][j])
		DFS(i+1,1,map);
        
		map[i][j]='*';
		if(i==1||check(i-1,j,map)==f[i-1][j])
		DFS(i+1,1,map);
		map[i][j]='.';
	}
	return 0;
}
int main()
{
	int t,i,j,num;
	char c;
	cin>>t;
	num=0;
	while(t--)
	{
		num++;
		cin>>n>>m;
		for(i=1;i<=n;i++)
			for(j=1;j<=m;j++)
			{
				cin>>c;
				f[i][j]=c-48;//保存数组
				map[i][j]='.';//初始化地图
			}
			X=0;f[1][0]=6;
			cout<<"Case "<<num<<":"<<endl;
			DFS(1,0,map);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值