注意到4*4=16,所以直接二进制枚举所有答案,然后存起来最后观察什么点是必须是雷,什么点不必要。然后答案里面对于是雷的,给二进制00变成01,对于不是雷的,二进制00变成10,最后要是二进制数是11,那就是不确定,否则就是确定的,代表所有的情况里面,只要是这个点是1,那么只可能是雷,等于2也同理。
#include <bits/stdc++.h>
#define il inline
using namespace std;
using ll = long long;
using ull = unsigned long long;
using int128=__int128_t;
const ll N = 1e6 + 5, mod =998244353, inf = 2e18;
const double esp=1e-9;
double PI=3.1415926;
void solve(){
int n=4;
vector<vector<int>>a(n+2,vector<int>(n+2));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
char x;
cin>>x;
if(x=='.'){
a[i][j]=-1;
}else{
a[i][j]=(x-'0');
}
}
}
vector<vector<int>>ans(n+2,vector<int>(n+2));
vector<vector<int>>b(n+2,vector<int>(n+2));
auto get=[&](int x,int y)->int{
int ans=0;
for(int i=-1;i<=1;i++){
for(int j=-1;j<=1;j++){
ans+=b[x+i][y+j];
}
}
return ans;
};
for(int mask=0;mask<(1<<16);mask++){
int now=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if((mask>>now)&1){
b[i][j]=1;
}else{
b[i][j]=0;
}
now++;
}
}
bool ok=true;
for(int i=1;i<=n&&ok;i++){
for(int j=1;j<=n&&ok;j++){
if(a[i][j]!=-1&&b[i][j]){
ok=false;
break;
}
if(a[i][j]!=-1){
int ans=get(i,j);
if(ans!=a[i][j]){
ok=false;
break;
}
}
}
}
if(ok){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(b[i][j]){
ans[i][j]|=1;// 有一种方案这里是雷
}else{
ans[i][j]|=2;// 有一种方案这里不是雷
}
}
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(a[i][j]!=-1){
cout<<a[i][j];
}else{
if(ans[i][j]==2){
cout<<"O";
}else if(ans[i][j]==1){
cout<<"X";
}else{
cout<<'.';
}
}
}
cout<<'\n';
}
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}

京公网安备 11010502036488号