Sudoku Sudoku
Topic address: https: //ac.nowcoder.com/acm/problem/51013
The meaning of problems
Programming 9x9 Sudoku
Entry
The number of 9x9 single input as a string of 81 characters, '.' Represents the desired number of filled.
In 'end' as a terminator
Export
Different forms of input, 81 numeric characters.
answer
State Reduction: Because Sudoku need to ensure that each row, each column, each house numbers different from each other, it can be said that this three cases in binary form, such as:
lifting part of a Sudoku, the first line first column, the first house:
? 71 ?? 4958
? 35
?. 8. 4
. 9
?
1
?
. 6
. 8
The first row is expressed as 000,100,110: if this number i.e. the flag is 0, then no flag is 1, for convenience of storage, preservation into decimal, i.e., 38
in the first column is represented as 000,010,010
first house expressed as 100,100,010
So only these three cases, "and" operation can be obtained, both for position 1, the obtained decimal number, and then sequentially obtained by lowbit obtained, each represents a number, it is only necessary to record all null values then you can get through the bit operation last answer to all null values dfs.
Because the data to ensure a solution, only need to output to meet a Sudoku solution can, in the end satisfy the conditions to fill to return, therefore, which take less likelihood of nulls filling in, to avoid the back too many times, this optimization need to add to this question too.
Code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 12
#define maxm 100
#define INF 2147483640
#define IOS ios::sync_with_stdio(false)
#define mod 10007
struct node{
int x,y;
};
int ff[N][N];
int R[N],C[N],G[N/3][N/3]; //状态压缩,1表示空值
vector<node>V; //记录所有空值的坐标
int mp[1<<N],ones[1<<N];
int lowbit(int i) //返回低位1
{
return i&(-i);
}
int get_num(int x,int y) //得到当前坐标,可以放那些数,返回状态压缩的值
{
return R[x]&C[y]&G[x/3][y/3];
}
int get_one(int x)
{
int cnt=0;
while(x)
{
if(x%2==1)
cnt++;
x=x>>1;
}
return cnt;
}
bool dfs(int cur)
{
if(cur==V.size())
return true;
int minv=12,id=0;
for(int i=0;i<V.size();i++)
if(ff[V[i].x][V[i].y]==0)
{
int t=ones[get_num(V[i].x,V[i].y)];
if(t<minv)
{
minv=t;
id=i;
}
}
node tt=V[id];
for(int i=get_num(tt.x,tt.y);i;i-=lowbit(i))
{
int va=lowbit(i);
ff[tt.x][tt.y]=mp[va];
R[tt.x]-=va;
C[tt.y]-=va;
G[tt.x/3][tt.y/3]-=va;
if(dfs(cur+1))
return true;
R[tt.x]+=va;
C[tt.y]+=va;
G[tt.x/3][tt.y/3]+=va;
ff[tt.x][tt.y]=0;
}
return false;
}
void init()
{
V.clear();
for(int i=0;i<N;i++)
{
R[i]=(1<<9)-1;
C[i]=(1<<9)-1;
}
for(int i=0;i<N/3;i++)
for(int j=0;j<N/3;j++)
G[i][j]=(1<<9)-1;
}
int main()
{
IOS;
for(int i=0;i<9;i++)
mp[1<<i]=i+1;
for(int i=0;i<(1<<N);i++)
ones[i]=get_one(i);
string str;
while(true)
{
cin>>str;
if(str[0]=='e')
break;
init();
for(int i=0; i<9; i++)
for(int j=0; j<9; j++)
{
if(str[i*9+j]=='.')
{
ff[i][j]=0;
V.push_back(node{i,j});
}
else
{
ff[i][j]=str[i*9+j]-48;
int t=ff[i][j];
R[i]-=(1<<t-1);
C[j]-=(1<<t-1);
G[i/3][j/3]-=(1<<t-1);
}
}
dfs(0);
string ans="";
for(int i=0; i<9; i++)
for(int j=0; j<9; j++)
ans.push_back(ff[i][j]+48);
cout<<ans<<"\n";
}
return 0;
}