坑爹的数独呀!又是搜索,又是剪枝~~~
代码如下:
#include<iostream>
#include<stdio.h>
#include<string.h>
const int MAX_COLOUMN=81+9*9+9*9+9*9+2;
const int MAX_ROW=81*9+2;
int cnt[MAX_COLOUMN];
int most,coloumn;
bool ans[MAX_ROW];
struct Point
{
int up,down,left,right;
int coloumn;
int row;
}node[MAX_ROW*MAX_COLOUMN+MAX_COLOUMN];
void init(int m)
{
int i;
for(i=0;i<m;i++)
{
node[i].down=i;
node[i].up=i;
node[i].coloumn=i;
node[i].left=i-1;
node[i].right=i+1;
cnt[i]=0;
}
node[0].left=m;
node[m].right=0;
}
void remove (int c)
{
node[node[c].right].left=node[c].left;
node[node[c].left].right=node[c].right;
int t,tt;
for(t=node[c].down;t!=c;t=node[t].down)
{
for(tt=node[t].right;tt!=t;tt=node[tt].right)
{
cnt[node[tt].coloumn]--;
node[node[tt].down].up=node[tt].up;
node[node[tt].up].down=node[tt].down;
}
}
}
void resume(int c)
{
int t,tt;
for(t=node[c].up;t!=c;t=node[t].up)
{
for(tt=node[t].left;tt!=t;tt=node[tt].left)
{
cnt[node[tt].coloumn]++;
node[node[tt].up].down=tt;
node[node[tt].down].up=tt;
}
}
node[node[c].right].left=c;
node[node[c].left].right=c;
}
bool dfs(int k)
{
int i,j;
if(k>=most) return false;
if(node[coloumn].right==coloumn)
{
if(k<most)
most=k;
return true;
}
int t=coloumn+1;
int c;
for(i=node[coloumn].right;i!=coloumn;i=node[i].right)
{
if(cnt[i]<t)
{
c=i;t=cnt[i];
if(t==1) break;
}
}
remove(c);
for(i=node[c].down;i!=c;i=node[i].down)
{
for(j=node[i].right;j!=i;j=node[j].right)
{
remove(node[j].coloumn);
}
ans[node[j].row]=true;
if(dfs(k+1))
{
return true;
}
ans[node[j].row]=false;
for(j=node[j].left;j!=i;j=node[j].left)
{
resume(node[j].coloumn);
}
}
resume(c);
return false;
}
bool graph[MAX_ROW][MAX_COLOUMN];
void addrow(int i,int j,int k)
{
int curr=(i*9+j)*9+k;
graph[curr][(i*9+j)]=true;
graph[curr][81+i*9+k]=true;
graph[curr][81+81+j*9+k]=true;
int tr=i/3;
int tc=j/3;
graph[curr][81+81+81+(tr*3+tc)*9+k]=true;
}
char str[MAX_ROW];
int main()
{
int N,M,i,j,k;
while(scanf("%s",str)!=EOF)
{
if(strcmp(str,"end")==0) break;
N=81*9;
M=9*9+9*9+9*9+9*9;
coloumn=M;
int cur=coloumn+1;
init(coloumn);
memset(graph,0,sizeof(graph));
for(i=0;i<9;i++)
for(j=0;j<9;j++)
{
if(str[i*9+j]=='.')
{
for(k=0;k<9;k++)
{
addrow(i,j,k);
}
continue;
}
k=str[i*9+j]-'1';
addrow(i,j,k);
}
for(i=0;i<N;i++)
{
int start=cur;
int pre=cur;
for(j=0;j<M;j++)
{
if(graph[i][j])
{
int pos=j;
node[cur].up=node[pos].up;
node[node[pos].up].down=cur;
node[cur].down=pos;
node[pos].up=cur;
cnt[pos]++;
node[cur].coloumn=pos;
node[cur].left=pre;
node[pre].right=cur;
node[cur].right=start;
node[start].left=cur;
node[cur].row=i;
pre=cur++;
}
}
}
most=N+1;
memset(ans,false,sizeof(ans));
dfs(0);
for(i=0;i<81;i++)
for(j=0;j<9;j++)
if(ans[i*9+j])
{
printf("%d",j+1);
break;
}
printf("\n");
}
return 0;
}