本来以为跟之前的做的一个4*4一样的一个题目,用普通的dfs去解决,但是开始dfs会输出各个答案,在加入flag之后使他停止在输出一组上,但是还是超时
超时代码
#include <iostream>
#include<cstring>
using namespace std;
int vis[15][15];
char tu[15][15];
int ju(int r,int l)
{
for(int i=0;i<9;i++)
{
if(tu[i][l]==tu[r][l]&&i!=r)
return 0;
}
for(int i=0;i<9;i++)
{
if(tu[r][i]==tu[r][l]&&i!=l)
return 0;
}
int mr=r;
int ml=l;
while(mr%3!=0)
mr--;
while(ml%3!=0)
ml--;
for(int i=mr;i<=mr+2;i++)
{
for(int j=ml;j<ml+2;j++)
{
if(tu[i][j]==tu[r][l]&&i!=r&&j!=l)
return 0;
}
}
return 1;
}
int flag=0;
void dfs(int x)
{
if(x==9*9)
{ if(flag)
return ;
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
cout<<tu[i][j];
}
flag=1;
cout<<endl;
return ;
}
else
{
int r=x/9;
int l=x%9;
if(tu[r][l]=='.')
{
if(flag)
return;
for(int k=1;k<=9;k++)
{ if(flag)
return;
tu[r][l]='0'+k;
if(ju(r,l))
{
dfs(x+1);
}
}
tu[r][l]='.';
}
else
{
dfs(x+1);
}
}
if(flag)
return;
}
int main()
{ int flagg=0;
while(1)
{ flagg=0;
memset(tu,0,sizeof(tu));
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
cin>>tu[i][j];
if(tu[i][j]=='d')
{
flagg=1;break;
}
}
if(flagg)
break;
}
if(flagg)
break;
flag=0;
dfs(0);
}
// cout << "Hello world!" << endl;
return 0;
}
搜了一下题解之后发现是一种dance links 的一种算法
这个超好的 博客将DLX的!点击打开链接
这里引用一个题解
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<algorithm>
using namespace std;
// 列:(行+列+块)*9种可能+9*9个格子
// 行: 9*9*9 表示第i行第j列填k
const int MAXN=(9+9+9)*9+9*9+9*9*9*9*9*4+10;
#define INF 0xFFFFFF
int size;
int head,sz;
int U[MAXN],D[MAXN],L[MAXN],R[MAXN];
int H[MAXN],ROW[MAXN],C[MAXN],S[MAXN],O[MAXN];
void remove(int c)
{
L[R[c]]=L[c];
R[L[c]]=R[c];
for(int i=D[c];i!=c;i=D[i])
{
for(int j=R[i];j!=i;j=R[j])
{
U[D[j]]=U[j];
D[U[j]]=D[j];
--S[C[j]];
}
}
}
void resume(int c)
{
for(int i=U[c];i!=c;i=U[i])
{
for(int j=L[i];j!=i;j=L[j])
{
++S[C[j]];
U[D[j]]=j;
D[U[j]]=j;
}
}
L[R[c]]=c;
R[L[c]]=c;
}
bool dfs(int k)
{
if(R[head]==head)
{
sort(O,O+9*9);
int p=0;
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
int num=O[p++];
//cout<<num<<endl;
num=num-(i*9+j)*9;
printf("%d",num);
}
}
printf("\n");
return true;
}
int s=INF,c;
for (int t=R[head];t!=head;t=R[t])
{
if (S[t]<s)
{
s=S[t];
c=t;
}
}
remove(c);
for(int i=D[c];i!=c;i=D[i])
{
O[k]=ROW[i];
for(int j=R[i];j!=i;j=R[j])
remove(C[j]);
if(dfs(k+1))
return true;
for(int j=L[i];j!=i;j=L[j])
resume(C[j]);
}
resume(c);
return false;
}
void initDL(int n)
{
head=0;
for(int i=0;i<=n;i++)
{
U[i]=i;D[i]=i;
L[i]=i-1;R[i]=i+1;
S[i]=0;
}
R[n]=0;L[0]=n;S[0]=INF+1;
sz=n+1;
memset(H,0,sizeof(H));
}
void insert(int i, int j)
{
if(H[i])
{
L[sz]=L[H[i]];
R[sz]=H[i];
L[R[sz]]=sz;
R[L[sz]]=sz;
}
else
{
L[sz]=sz;
R[sz]=sz;
H[i]=sz;
}
U[sz]=U[j];
D[sz]=j;
U[D[sz]]=sz;
D[U[sz]]=sz;
C[sz]=j;
ROW[sz]=i;
++S[j];
++sz;
}
char str[200];
void build()
{
int p=0;
initDL(9*9*4);
for(int i=0;i<9;i++)
for(int j=1;j<=9;j++,p++)
{
int base=(i*9+j-1)*9;
if(str[p]=='.')
{
for(int k=1;k<=9;k++)
{
int r;
r=base+k;
//第i行有数字k
insert(r,i*9+k);
//第j列有数字k
insert(r,9*9+(j-1)*9+k);
//第k块有数字k
int block=(j-1)/3*3+i/3;
insert(r,9*9*2+block*9+k);
//第i行j列有一个数字(限制一个格子只填一个数)
insert(r,9*9*3+i*9+j);
}
}
else
{
int k=str[p]-'0';
int r=base+k;
//第i行有数字k
insert(r,i*9+k);
//第j列有数字k
insert(r,9*9+(j-1)*9+k);
//第k块有数字k
int block=(j-1)/3*3+i/3;
insert(r,9*9*2+block*9+k);
//第i行j列有一个数字(限制一个格子只填一个数)
insert(r,9*9*3+i*9+j);
}
}
}
int main()
{
size=9; //9*9数独
while(~scanf("%s",str))
{
if(strcmp(str,"end")==0)
break;
build();
dfs(0);
}
return 0;
}