状态枚举,0表示非雷,1表示雷,总共2的16次方种情况,如果出现雷在标数字的点位直接跳过,或者标数字点位周围的雷的数量不对也跳过,否则就是合法的方案,对于sta==1,对点位标记|1,sta==0,点位标记|2,那么,假设这个点最后标记结果为3,就说明这个点可能是雷也可能不是雷,则输出'.',否则就按照标记的结果输出,当然,点位是数字的话就直接输出数字。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
char c[5][5];
int cnt[5][5];
int dirx[8]={1,-1,-1,1,1,-1,0,0};
int diry[8]={1,-1,1,-1,0,0,1,-1};
int d;
int range = 1<<16;
bool check(ll x)
{
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
{
int w = (i-1)*4+(j-1);
int sta = (x>>w)&1;
if(sta==1&&c[i][j]>='0'&&c[i][j]<='9')return false;
if(c[i][j]>='0'&&c[i][j]<='9')
{
int cur = c[i][j]-'0';
int cnt = 0;
for(int k=0;k<8;k++)
{
int cx = i+dirx[k];
int cy = j+diry[k];
if(cx<1||cy<1||cx>4||cy>4)continue;
int w2 = (cx-1)*4+(cy-1);
int sta2 = (x>>w2)&1;
if(sta2)cnt++;
}
if(cnt!=cur)return false;
}
}
}
return true;
}
int main()
{
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)cin>>c[i][j];
}
for(int i=0;i<=range-1;i++)
{
if(check(i))
{
for(int a=1;a<=4;a++)
{
for(int b=1;b<=4;b++)
{
int w = (a-1)*4+(b-1);
int sta = (i>>w)&1;
if(sta)cnt[a][b]|=1;
else cnt[a][b]|=2;
}
}
}
}
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
{
if(c[i][j]>='0'&&c[i][j]<='9')cout<<c[i][j];
else if(cnt[i][j]==3)cout<<'.';
else if(cnt[i][j]==1)cout<<'X';
else cout<<'O';
}
cout<<endl;
}
return 0;
}

京公网安备 11010502036488号