AcWing 166. 数独
原题链接
中等
作者:
小生不才
,
2021-03-11 20:51:28
,
所有人可见
,
阅读 308
#include<iostream>
using namespace std;
const int n=9;
int mp[1<<n]; //记录1所在位置,mp[2]=1 mp[8]=3
int ones[1<<n]; //记录一个数二进制表示有多少个1
int col[n],row[n],cell[3][3];//行 列 和各个小九宫格可以放那些位置
char str[100];
inline int lowbit(int x)//内联函数 省去调用时间 返回最后一位1
{
return x & -x;
}
inline int get(int x,int y)
{
return row[x] & col[y] & cell[x/3][y/3];
}
void init()
{
for(int i=0;i<n;i++) col[i]=row[i]=(1<<n)-1;//默认每一个数字都可放
for(int i=0;i<3;i++)
for(int j=0;j<3;j++) cell[i][j]=(1<<n)-1;
}
bool dfs(int cnt)
{
if(!cnt) return true;
//找可能解最少的空格
int minx=99,x,y;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(str[i*9+j]=='.')
{
int t=ones[get(i,j)];
if(minx>t)
{
minx=t;
x=i;y=j;
}
}
for(int i=get(x,y);i;i -= lowbit(i))
{
int t=mp[lowbit(i)];
row[x]-=1<<t;
col[y]-=1<<t;
cell[x/3][y/3]-=1<<t;
str[x*9+y]='1'+t;
if(dfs(cnt-1)) return true;
row[x]+=1<<t;
col[y]+=1<<t;
cell[x/3][y/3]+=1<<t;
str[x*9+y]='.';
}
return false;
}
int main()
{
for(int i=0;i<n;i++) mp[1<<i] = i;
for(int i=0;i<1<<n;i++)
{
int sum=0;
for(int j=i;j;j-=lowbit(j)) sum++;
ones[i]=sum;
}
while(cin>>str,str[0]!='e')
{
init();
int cnt=0;
for(int i=0,k=0;i<n;i++)
for(int j=0;j<n;j++,k++)
{
if(str[k]!='.')
{
int t=str[k]-'1';
row[i]-=1<<t;
col[j]-=1<<t;
cell[i/3][j/3]-=1<<t;
}
else cnt++;
}
dfs(cnt);
cout<<str<<endl;
}
return 0;
}