Mine Number
Time Limit: 1000ms Memory limit: 65536K
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; }