解题报告:其实这题我以前做过,但是我给忘记了怎么剪枝,刚好蓝桥杯训练到了这题,那就补一补吧,主要是要把行、列、3x3小矩阵这三个信息的状态压缩,然后某点x,y可选的值在他们状态相与的情况下才满足,然后每次搜索,搜索分支最小的搜索,还有个小优化就是lowbit运算,返回二进制最近的1的数值,然后还要预处理出来1<<i的值就可以了。

#include<iostream>
using namespace std;
string str;
const   int N=9;
int one[1<<N],map[1<<N];
int row[N],col[N],g[N/3][N/3];
int lowbit(int x)
{
   
    return x&-x;
}
int get(int x,int y)
{
   
    return row[x]&col[y]&g[x/3][y/3];
}
void init()
{
   
    for(int i=0;i<N;i++)
    {
   row[i]=(1<<N)-1;
    col[i]=(1<<N)-1;
    }
    for(int i=0;i<N/3;i++)
    for(int j=0;j<N/3;j++)
    g[i][j]=(1<< N )-1;
}
bool dfs(int cnt)
{
   
    if(!cnt)    return true;
    int minv=10;
    int x=0,y=0;
    for(int i=0;i<N;i++)
    for (int j=0; j<N; j++)
    {
   
        if(str[i*N+j]=='.')
        {
   
            int t=one[get(i,j)];
            if(t<minv)
            {
   
                minv=t;
                x=i;
                y=j;
              // cout<<x<<' '<<y<<endl;
            }
        }
    } 
    int tt=get(x,y);
// cout<<x<<' '<<y<<endl;
  // cout<<t<<endl;
    for(int i=tt ;i ;i-=lowbit(i))
   {
   
       int bb=map[lowbit(i)];
        row[x]-=1<<bb;
        col[y]-= 1<<bb;
        g[x/3][y/3] -= 1<<bb;
        char cc='1'+bb;
        str[x*N+y]=cc;
        if(dfs(cnt-1)) return true;
        str[x*N+y]='.';
        row[x]+= 1<<bb;
        col[y]+=1<<bb;
        g[x/3][y/3] += 1<<bb;
   }
    return false;
}
int main()
{
     
    for(int i=0;i< N;i++)    map[1<<i]=i;
    for(int i=0;i<1<<N;i++)
    for(int j=0;j<N;j++)
    if((i>>j)&1)  one[i]++;
// exit(0);
    while(cin>> str , str != "end")
    {
   
        int cnt=0;
        init();
        for(int i=0;i<str.size();i++)
        {
   
            if(str[i]!='.')
            {
   
                int t=str[i]-'1';
           // cout<<t<<endl;
                row[i/N] -= 1<<t;
                col[i%N] -= 1<<t;
                int tx=i/N;
                int ty=i%N;
                g[tx/3][ty/3] -= 1<<t;
            }
            else
            cnt++;
        }
     // cout<<1<<N-1<<' '<<(1<<N)-1<<endl;
    // cout<<cnt<<endl;
        dfs(cnt); //exit(0);
        cout<<str<<endl;
    }
}