题意:给一幅图说明周围的地雷数,要你输出地雷图,确保答案唯一。
思路:枚举第一行的地雷,然后往下递推判断得到的地雷图是否符合原图要求。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
int n,m;
char num_mat[25][25];
char now_mat[25][25];
int getSomeSum(int i,int j)
{
int num=0;
if(now_mat[i][j]=='*') ++num;
if(i-1>=1&&now_mat[i-1][j]=='*') ++num;
if(j-1>=0&&now_mat[i][j-1]=='*') ++num;
if(j+1<m&&now_mat[i][j+1]=='*') ++num;
return num;
}
bool checkNow(int row,int S)
{
for(int i=0; i<m; ++i)
{
int num=0;
if(S&(1<<i)) ++num;
if(i+1<m&&(S&(1<<(i+1)))) ++num;
if(i-1>=0&&(S&(1<<(i-1)))) ++num;
if(now_mat[row-1][i]=='*') ++num;
if(num>num_mat[row][i]-'0')
return false;
}
return true;
}
void setNow(int row,int S)
{
for(int i=0; i<m; ++i)
if(S&(1<<i))
now_mat[row][i]='*';
else
now_mat[row][i]='.';
}
bool setNext(int row)
{
for(int i=0; i<m; ++i)
{
int c=getSomeSum(row-1,i);
int num=num_mat[row-1][i]-'0';
if(c+1==num) now_mat[row][i]='*';
else if(c==num) now_mat[row][i]='.';
else return false;
}
return true;
}
bool checkLast(int row)
{
for(int i=0; i<m; ++i)
if(getSomeSum(row,i)!=num_mat[row][i]-'0')
return false;
return true;
}
int main()
{
int T,kase=0;
scanf("%d",&T);
while(T--)
{
memset(now_mat,0,sizeof(now_mat));
scanf("%d%d",&n,&m);
getchar();
for(int i=1; i<=n; ++i)
gets(num_mat[i]);
for(int i=0; i<(1<<m); ++i)
{
if(!checkNow(1,i)) continue;
setNow(1,i);
bool ok=true;
for(int j=2; j<=n&&ok; ++j)
{
if(!setNext(j))
ok=false;
}
if(!ok) continue;
if(checkLast(n))
break;
else
memset(now_mat,0,sizeof(now_mat));
}
printf("Case %d:\n",++kase);
for(int i=1; i<=n; ++i)
puts(now_mat[i]);
}
return 0;
}