枚举第一行即可,与训练指南上例题相似
代码如下:
#include <cstdio>
#include <cstring>
int a[21][21],b[21][21],n,m;
char s[25][25];
bool check_line(int x)
{
int ans=b[0][x];
if (x)
ans+=b[0][x-1];
if (x<m-1)
ans+=b[0][x+1];
if (ans==a[0][x] || ans+1==a[0][x])
return true;
return false;
}
int g(int x,int y)
{
int ans=b[x][y];
if (x)
ans+=b[x-1][y];
if (y)
ans+=b[x][y-1];
if (y<m-1)
ans+=b[x][y+1];
return ans;
}
bool f(int s)
{
for (int i=0; i<m; ++i)
if (s & (1<<i))
b[0][i]=1;
else
b[0][i]=0;
if (n==1)
{
for (int i=0; i<m; ++i)
if (g(0,i)!=a[0][i])
return false;
return true;
}
int i,j;
for (i=0; i<m; ++i)
if (!check_line(i))
return false;
for (i=1; i<n; ++i)
for (j=0; j<m; ++j)
if (g(i-1,j)==a[i-1][j])
b[i][j]=0;
else if (g(i-1,j)+1==a[i-1][j])
b[i][j]=1;
else
return false;
for (i=0; i<m; ++i)
if (g(n-1,i)!=a[n-1][i])
return false;
return true;
}
int main()
{
int i,j,T,kcase=0;
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&n,&m);
getchar();
for (i=0; i<n; ++i)
scanf("%s",s[i]);
for (i=0; i<n; ++i)
for (j=0; j<m; ++j)
a[i][j]=s[i][j]-'0';
for (int s=0; s<(1<<m); ++s)
if (f(s))
break;
printf("Case %d:\n",++kcase);
for (i=0; i<n; ++i)
{
for (j=0; j<m; ++j)
if (b[i][j])
printf("*");
else
printf(".");
printf("\n");
}
}
return 0;
}