题解:B4167 [GXPC-S 2024] 扫雷

· · 题解

二进制的枚举&剪枝

基本题意简述

基本思路

#include<bits/stdc++.h>
using namespace std;
char maze[15][15];
int mul=1;
int ditu[15][15];
const int dx[8]={-1,-1,-1,0,0,1,1,1};
const int dy[8]={-1,0,1,-1,1,-1,0,1};
int n,m;
bool first=true;
bool corr=false;
bool bomb[11]={0,0,0,0,0,0,0,0,0,0,0};
struct un
{
    int x;
    int y;
}unk[15];//预处理 
int check()
{
    for(int k=1;k<=n;k++)
    {
        for(int l=1;l<=m;l++)
        {
            if(ditu[k][l]>=0&&ditu[k][l]<=8)
            {
                int cnt=0;
                for(int p=0;p<8;p++)
                {
                    if(maze[k+dx[p]][l+dy[p]]=='*')
                    {
                        cnt++;
                    }
                }
                if(cnt!=ditu[k][l])
                {
                    return 0;
                }
            }
        }
    }
    return 1;
}//检查函数,确认是否每一个数字都满足当前雷的排布 
int top=1;
int main()
{
    int t;
    cin>>t;
    for(int i=1;i<=t;i++)
    {
        memset(ditu,-1,sizeof(ditu));
        memset(bomb,0,sizeof(bomb));
        corr=false;
        mul=1;
        top=1;//多组数据时记得对每种需要的数据初始化 
        cin>>n>>m;
        for(int j=1;j<=n;j++)
        {
            for(int k=1;k<=m;k++)
            {
                cin>>maze[j][k];
                if(maze[j][k]=='?')
                {
                    unk[top].x=j;
                    unk[top].y=k;
                    top++;
                }
                if(maze[j][k]>='0'&&maze[j][k]<='8')
                {
                    ditu[j][k]=maze[j][k]-'0';
                }
            }
        }//输入字符,并分类处理 
        top--;
        for(int i=1;i<=top;i++)
        {
            mul=mul*2;
        }//如果此时没有问号字符,mul=1也会循环一次
        for(int j=0;j<mul;j++)//二进制的想法
        {
            int s=j;
            for(int k=top;k>0;k--)
            {
                bomb[k]=s%2;//反复对2取模,可以获取当前每个问号的状态 
                if(bomb[k])
                {
                    maze[unk[k].x][unk[k].y]='*';
                }
                else
                {
                    maze[unk[k].x][unk[k].y]='.';
                }
                s/=2;
            }
            if(check())
            {
                corr=true;
                cout<<"YES"<<endl;
                break;
            }
        }
        if(!corr)
        {
            cout<<"NO"<<endl;
        }//如果能走到这一步,那这种就一定不满足要求 
    }
    return 0;
}