原链接1:http://blog.sina.com.cn/s/blog_51cea4040100gxn1.html 这女娃子改变我对女性的看法 第一个代码和第三个第四个代码(靶形数独)来源于此链接。
原链接2:http://yzmduncan.iteye.com/blog/1151695
本文第一个代码建舞池既节省时间重要的的是耗时也少。建舞池耗时在0-1ms,对于大量测试来说正满足额外开销小的要求。解题时间两代码相差无几,是因为数组是随机存取,如换为链表作数据结构,第一个代码耗时少。第一个代码先把题目中已填的数做预处理减少的耗时不好统计,因为整个解题时间也就3ms。
DLX比一般DFS快的理由:
1:增加了行,列,宫中各九个候选数一共81*3=243个检测量,不但囊括了显隐唯一数技巧,还使探索指标增多。
2:删除修复,同行,列,宫候选数时有条不紊,remove和resume是绝配不需要另外的空间和时间。
#include<cstdlib>
#include<iostream>
#include<time.h>
using namespace std;
const int maxr=9*9*9+10;
const int maxc=9*9*4+10;
int L[maxc+maxr*5],R[maxc+maxr*5],U[maxc+maxr*5],D[maxc+maxr*5];
int S[maxc];
int nRow[maxc+maxr*5];
int nCol[maxc+maxr*5];
int head[10][10][10];
int outcome[59],o_sub;
int cnt;
int map[10][10]={0,0,0,0,0,0,0,0,0,0,
0,8,0,0,0,0,0,0,0,0,
0,0,0,3,6,0,0,0,0,0,
0,0,7,0,0,9,0,2,0,0,
0,0,5,0,0,0,7,0,0,0,
0,0,0,0,0,4,5,7,0,0,
0,0,0,0,1,0,0,0,3,0,
0,0,0,1,0,0,0,0,6,8,
0,0,0,8,5,0,0,0,1,0,
0,0,9,0,0,0,0,4,0,0};
bool init();
int subgrid(int,int);
void Ins_node(int,int);
void Remove(int);
void Resume(int);
bool dfs(int);
void print();
int test();
bool fun(int a[10]);
int subgrid(int i,int j)
{
i--; j--;
return (i/3)*3+(j/3+1);
if (i<=3 && j<=3) return 1;
if (i<=3 && j<=6) return 2;
if (i<=3 && j<=9) return 3;
if (i<=6 && j<=3) return 4;
if (i<=6 && j<=6) return 5;
if (i<=6 && j<=9) return 6;
if (i<=9 && j<=3) return 7;
if (i<=9 && j<=6) return 8;
if (i<=9 && j<=9) return 9;
}
void Ins_node(int c,int cnt)
{
U[D[c]]=cnt;
D[cnt]=D[c];
U[cnt]=c;
D[c]=cnt;
S[c]++;
nCol[cnt]=c;
}
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[nCol[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])
{
U[D[j]]=D[U[j]]=j;
S[nCol[j]]++;
}
L[R[c]]=R[L[c]]=c;
}
bool dfs(int k)
{
if (k>81) return true;
int c,minnum=INT_MAX;
for (int i=R[0];i!=0;i=R[i])
{
// if (!S[i]) return false;
if (S[i]<minnum)
{
minnum=S[i];
c=i;
}
}
Remove(c);
outcome[o_sub++]=c;
for (int i=D[c];i!=c;i=D[i])
{
int tmp=nRow[i];
map[tmp/100][(tmp/10)%10]=tmp%10;
for (int j=R[i];j!=i;j=R[j])
Remove(nCol[j]);
if (dfs(k+1)) return true;
for (int j=L[i];j!=i;j=L[j])
Resume(nCol[j]);
}
Resume(c);
o_sub--;
return false;
}
void print()
{
for(int i=1;i<=9;i++)
{
if((i-1)%3==0) printf("\n");
for(int j=1;j<=9;j++)
if((j-1)%3==0) { printf(" "); printf("%d ",map[i][j]);}
else printf("%d ",map[i][j]);
printf("\n");
}
}
int test()
{
int sum=0,i,j,aray[10];
for(int i=1;i<=9;i++)
{
sum=0;
for(int j=1;j<=9;j++)
{ sum+=map[i][j]; aray[j]=map[i][j];}
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
if(!fun(aray)) return 0;
}
for( j=1;j<=9;j++)
{
sum=0;
for(i=1;i<=9;i++)
{ sum+=map[i][j]; aray[i]=map[i][j];}
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
if(!fun(aray)) return 0;
}
for(int k=1;k<=9;k++)
{
sum=0;
int row=(k-1)/3*3+1,col=(k-1)%3*3+1,sub=1;
for(i=row;i<=row+2;i++)
for(j=col;j<=col+2;j++)
{ sum+=map[i][j]; aray[sub++]=map[i][j];}
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
if(!fun(aray)) return 0;
}
return 1;
}
bool fun( int a[10])
{
int i,j;
for(i=1;i<=8;i++)
{
if(*(a+i)==0) continue;
for(j=i+1;j<=9;j++)
if(*(a+i)==*(a+j)) return (false);
}
return (true);
}
int main()
{
freopen("d:\\c++\\数独12\\question\\question475.txt","w",stdout);
int op=1;
srand(time(0));
long time1,time2,time3=0;
time1=clock();
for (int i=0;i<=81*4;i++)
{
S[i]=0;
L[i]=i-1; R[i]=i+1;
U[i]=D[i]=i;
nCol[i]=0;
}
L[0]=81*4; R[81*4]=0;
cnt=81*4;
for (int i=1;i<=9;i++)
for (int j=1;j<=9;j++)
{
if (map[i][j])
{
int k=map[i][j];
for (int u=1;u<=4;u++)
{
L[cnt+u]=cnt+u-1;
R[cnt+u]=cnt+u+1;
nRow[cnt+u]=100*i+10*j+k;
}
L[cnt+1]=cnt+4; R[cnt+4]=cnt+1;
head[i][j][k]=cnt+1;
Ins_node((i-1)*9+j,cnt+1);
Ins_node(81+(i-1)*9+k,cnt+2);
Ins_node(81*2+(j-1)*9+k,cnt+3);
Ins_node(81*3+(subgrid(i,j)-1)*9+k,cnt+4);
cnt+=4;
}
else
for (int k=1;k<=9;k++)
{
for (int u=1;u<=4;u++)
{
L[cnt+u]=cnt+u-1;
R[cnt+u]=cnt+u+1;
nRow[cnt+u]=100*i+10*j+k;
}
L[cnt+1]=cnt+4; R[cnt+4]=cnt+1;
head[i][j][k]=cnt+1;
Ins_node((i-1)*9+j,cnt+1);
Ins_node(81+(i-1)*9+k,cnt+2);
Ins_node(81*2+(j-1)*9+k,cnt+3);
Ins_node(81*3+(subgrid(i,j)-1)*9+k,cnt+4);
cnt+=4;
}
}
time2=clock();
int k=0;
for (int i=1;i<=9;i++)
for (int j=1;j<=9;j++)
if (map[i][j])
{
k++;
Remove(nCol[head[i][j][map[i][j]]]);
for (int u=R[head[i][j][map[i][j]]];u!=head[i][j][map[i][j]];u=R[u])
Remove(nCol[u]);
}
dfs(k+1);
time3=clock();
if(test()) print();
else cout<<op<<endl;
cout<<"建舞池用时"<<time2-time1<<"ms"<<"解题用时"<<time3-time2<<"ms"<<endl;
}
#include <iostream>
#include<time.h>
using namespace std;
const int INF = 0x7fffffff;
const int NN = 350;
const int MM = 750;
int n,m; //列,行
int cntc[NN];
int L[NN*MM],R[NN*MM],U[NN*MM],D[NN*MM];
int C[NN*MM];
int head;
int mx[MM][NN];
int O[MM],idx;
int ans[10][10];
int map[10][10]={0,0,0,0,0,0,0,0,0,0,
0,8,0,0,0,0,0,0,0,0,
0,0,0,3,6,0,0,0,0,0,
0,0,7,0,0,9,0,2,0,0,
0,0,5,0,0,0,7,0,0,0,
0,0,0,0,0,4,5,7,0,0,
0,0,0,0,1,0,0,0,3,0,
0,0,0,1,0,0,0,0,6,8,
0,0,0,8,5,0,0,0,1,0,
0,0,9,0,0,0,0,4,0,0};
//删除列及其相应的行
void remove(int c)
{
int i,j;
L[R[c]] = L[c];
R[L[c]] = R[c];
for(i = D[c]; i != c; i = D[i])
{
for(j = R[i]; j != i; j = R[j])
{
U[D[j]] = U[j];
D[U[j]] = D[j];
cntc[C[j]]--;
}
}
}
//恢复列及其相应的行
void resume(int c)
{
int i,j;
R[L[c]] = c;
L[R[c]] = c;
for(i = D[c]; i != c; i = D[i])
{
for(j = R[i]; j != i; j = R[j])
{
U[D[j]] = j;
D[U[j]] = j;
cntc[C[j]]++;
}
}
}
bool dfs()
{
int i,j,c;
if(R[head] == head)
return true;
int min = INF;
for(i = R[head]; i != head; i = R[i])
{
if(cntc[i] < min)
{
min = cntc[i];
c = i;
}
}
remove(c);
for(i = D[c]; i != c; i = D[i])
{
//i是某点的序号,将该点所在行的行号保存
O[idx++] = (i-1)/n;
for(j = R[i]; j != i; j = R[j])
remove(C[j]);
if(dfs())
return true;
for(j = L[i]; j != i; j = L[j])
resume(C[j]);
idx--;
}
resume(c);
return false;
}
bool build()
{
int i,j,now,pre,first;
idx = head = 0;
for(i = 0; i < n; i++)
{
R[i] = i+1;
L[i+1] = i;
}
R[n] = 0;
L[0] = n;
//列双向链表
for(j = 1; j <= n; j++)
{
pre = j;
cntc[j] = 0;
for(i = 1; i <= m; i++)
{
if(mx[i][j])
{
cntc[j]++;
now = i*n+j;
C[now] = j;
D[pre] = now;
U[now] = pre;
pre = now;
}
}
U[j] = pre;
D[pre] = j;
if(cntc[j] == 0)
return false;
}
//行双向链表
for(i = 1; i <= m; i++)
{
pre = first = -1;
for(j = 1; j <= n; j++)
{
if(mx[i][j])
{
now = i*n+j;
if(pre == -1)
first = now;
else
{
R[pre] = now;
L[now] = pre;
}
pre = now;
}
}
if(first != -1)
{
R[pre] = first;
L[first] = pre;
}
}
return true;
}
void print()
{
int i,j;
int x,y,k;
for(i = 0; i < idx; i++)
{
int r = O[i];
k = r%9;
if(k==0) k = 9;
int num = (r - k)/9 + 1;
y = num%9;
if(y == 0) y = 9;
x = (num-y)/9 + 1;
ans[x][y] = k;
}
if(idx == 0)
printf("impossible\n");
else
{
for(i = 1; i <= 9; i++)
{
for(j = 1; j <= 9; j++)
printf("%d",ans[i][j]);
printf("\n");
}
}
}
int main()
{
int i,j,k;
long time1,time2,time3;
char s[10][10];
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
if(map[i][j]) s[i][j]=48+map[i][j];
else s[i][j]='?';
memset(mx,0,sizeof(mx));
time1=clock();
for(i = 1; i <= 9; i++)
{
for(j = 1; j <= 9; j++)
{
int t = (i-1)*9 + j;
if(s[i][j] == '?')
{
for(k = 1; k <= 9; k++)
{
mx[9*(t-1)+k][t] = 1; //81grid 每个小格只能放一个数字
mx[9*(t-1)+k][81+(i-1)*9+k] = 1; //9row 每行数字k只能出现一次
mx[9*(t-1)+k][162+(j-1)*9+k] = 1; //9col 每列数字k只能出现一次
mx[9*(t-1)+k][243+((i-1)/3*3+(j+2)/3-1)*9+k] = 1; //subgrid 每个3*3格子数字k只能出现一次
}
}
else
{
k = s[i][j] - '0';
mx[9*(t-1)+k][t] = 1; //81grid
mx[9*(t-1)+k][81+(i-1)*9+k] = 1; //9row
mx[9*(t-1)+k][162+(j-1)*9+k] = 1; //9col
mx[9*(t-1)+k][243+((i-1)/3*3+(j+2)/3-1)*9+k] = 1; //subgrid
}
}
}
n = 324;
m = 729;
build();
time2=clock();
dfs();
time3=clock();
print();
cout<<"建舞池用时"<<time2-time1<<"ms"<<"解题用时"<<time3-time2<<"ms"<<endl;
getchar(); getchar();
return 0;
}
#include<iostream>
using namespace std;
const int maxr=9*9*9+10;
const int maxc=9*9*4+10;
int L[maxc+maxr*5],R[maxc+maxr*5],U[maxc+maxr*5],D[maxc+maxr*5];
int S[maxc];
int nRow[maxc+maxr*5];
int nCol[maxc+maxr*5];
int head[10][10][10];
int cnt;
int map[10][10];
int data1[9][9]=
{7,0,0,9,0,0,0,0,1,
1,0,0,0,0,5,9,0,0,
0,0,0,2,0,0,0,8,0,
0,0,5,0,2,0,0,0,3,
0,0,0,0,0,0,6,4,8,
4,1,3,0,0,0,0,0,0,
0,0,7,0,0,2,0,9,0,
2,0,1,0,6,0,8,0,4,
0,8,0,5,0,4,0,1,2};
int data2[9][9]=
{0,0,0,7,0,2,4,5,3,
9,0,0,0,0,8,0,0,0,
7,4,0,0,0,5,0,1,0,
1,9,5,0,8,0,0,0,0,
0,7,0,0,0,0,0,2,5,
0,3,0,5,7,9,1,0,8,
0,0,0,6,0,1,0,0,0,
0,6,0,9,0,0,0,0,1,
0,0,0,0,0,0,0,0,6};
int best=-1,SCORE=0;
int score[10][10]=
{
{0,0,0,0,0,0,0,0,0,0},
{0,6,6,6,6,6,6,6,6,6},
{0,6,7,7,7,7,7,7,7,6},
{0,6,7,8,8,8,8,8,7,6},
{0,6,7,8,9,9,9,8,7,6},
{0,6,7,8,9,10,9,8,7,6},
{0,6,7,8,9,9,9,8,7,6},
{0,6,7,8,8,8,8,8,7,6},
{0,6,7,7,7,7,7,7,7,6},
{0,6,6,6,6,6,6,6,6,6}
};
int subgrid(int i,int j)
{
i--; j--;
return (i/3)*3+(j/3+1);
}
void Ins_node(int c,int cnt)
{
U[D[c]]=cnt;
D[cnt]=D[c];
U[cnt]=c;
D[c]=cnt;
S[c]++;
nCol[cnt]=c;
}
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[nCol[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])
{
U[D[j]]=D[U[j]]=j;
S[nCol[j]]++;
}
L[R[c]]=R[L[c]]=c;
}
void dfs(int k)
{
if (k>81)
{
cout<<SCORE<<endl;
if (SCORE>best) best=SCORE;
return;
}
int c,minnum=INT_MAX;
for (int i=R[0];i!=0;i=R[i])
{
if (!S[i]) return;
if (S[i]<minnum)
{
minnum=S[i];
c=i;
}
}
Remove(c);
for (int i=D[c];i!=c;i=D[i])
{
int tmp=nRow[i];
SCORE=SCORE+(tmp%10)*(score[tmp/100][(tmp/10)%10]);
for (int j=R[i];j!=i;j=R[j])
Remove(nCol[j]);
dfs(k+1);
SCORE=SCORE-(tmp%10)*(score[tmp/100][(tmp/10)%10]);
for (int j=L[i];j!=i;j=L[j])
Resume(nCol[j]);
}
Resume(c);
}
int main()
{
freopen("d:\\c++\\数独12\\question\\question474.txt","w",stdout);
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
map[i][j]=data1[i-1][j-1];
for (int i=0;i<=81*4;i++)
{
S[i]=0;
L[i]=i-1; R[i]=i+1;
U[i]=D[i]=i;
nCol[i]=0;
}
L[0]=81*4; R[81*4]=0;
cnt=81*4;
for (int i=1;i<=9;i++)
for (int j=1;j<=9;j++)
{
if (map[i][j])
{
int k=map[i][j];
for (int u=1;u<=4;u++)
{
L[cnt+u]=cnt+u-1;
R[cnt+u]=cnt+u+1;
nRow[cnt+u]=100*i+10*j+k;
}
L[cnt+1]=cnt+4; R[cnt+4]=cnt+1;
head[i][j][k]=cnt+1;
Ins_node((i-1)*9+j,cnt+1);
Ins_node(81+(i-1)*9+k,cnt+2);
Ins_node(81*2+(j-1)*9+k,cnt+3);
Ins_node(81*3+(subgrid(i,j)-1)*9+k,cnt+4);
cnt+=4;
}
else
for (int k=1;k<=9;k++)
{
for (int u=1;u<=4;u++)
{
L[cnt+u]=cnt+u-1;
R[cnt+u]=cnt+u+1;
nRow[cnt+u]=100*i+10*j+k;
}
L[cnt+1]=cnt+4; R[cnt+4]=cnt+1;
head[i][j][k]=cnt+1;
Ins_node((i-1)*9+j,cnt+1);
Ins_node(81+(i-1)*9+k,cnt+2);
Ins_node(81*2+(j-1)*9+k,cnt+3);
Ins_node(81*3+(subgrid(i,j)-1)*9+k,cnt+4);
cnt+=4;
}
}
int k=0;
for (int i=1;i<=9;i++)
for (int j=1;j<=9;j++)
if (map[i][j])
{
k++;
SCORE+=(map[i][j])*score[i][j];
Remove(nCol[head[i][j][map[i][j]]]);
for (int u=R[head[i][j][map[i][j]]];u!=head[i][j][map[i][j]];u=R[u])
Remove(nCol[u]);
}
dfs(k+1);
printf("%d\n",best);
fclose(stdout);
return 0;
}
//http://blog.csdn.net/nhczp/article/details/1498868 这个链接产生多解的题目 并输出原始终盘(用来挖洞),以及题目,还有这个题目的一切解题结果
//http://blog.sina.com.cn/s/blog_51cea4040100gxn1.html 这个链接解靶形数独并输出最好得分
//输出到屏幕终端的是有都少个解法 输出到一个文件的是原始终盘(用来挖洞),以及题目,还有这个题目的一切解题结果, 输出到另一个文件的结果是每一个解题结果对应的分数最后输出最大分数
//速度真快,第一种解题用的是dfs第二种解题用的是dlx(解靶形数独) 两种都快啊
//如果有靶形数独题目,还可以直接输入,data1,和data2就是两个靶形数独题目,在main函数里只需要屏蔽一些代码启用另一些代码就可测试特定的靶形数独题目
#include "time.h"
#include<cstdlib>
#include<iostream>
#include<fstream>
using namespace std;
ofstream out_stream;
enum{ANY=0,ALL=1};
int map_exchange[9][9];
int smod;
int solves;
const int maxr=9*9*9+10;
const int maxc=9*9*4+10;
int L[maxc+maxr*5],R[maxc+maxr*5],U[maxc+maxr*5],D[maxc+maxr*5];
int S[maxc];
int nRow[maxc+maxr*5];
int nCol[maxc+maxr*5];
int head[10][10][10];
int cnt;
int map[10][10];
int data1[9][9]=
{7,0,0,9,0,0,0,0,1,
1,0,0,0,0,5,9,0,0,
0,0,0,2,0,0,0,8,0,
0,0,5,0,2,0,0,0,3,
0,0,0,0,0,0,6,4,8,
4,1,3,0,0,0,0,0,0,
0,0,7,0,0,2,0,9,0,
2,0,1,0,6,0,8,0,4,
0,8,0,5,0,4,0,1,2};
int data2[9][9]=
{0,0,0,7,0,2,4,5,3,
9,0,0,0,0,8,0,0,0,
7,4,0,0,0,5,0,1,0,
1,9,5,0,8,0,0,0,0,
0,7,0,0,0,0,0,2,5,
0,3,0,5,7,9,1,0,8,
0,0,0,6,0,1,0,0,0,
0,6,0,9,0,0,0,0,1,
0,0,0,0,0,0,0,0,6};
int best=-1,SCORE=0;
int score[10][10]=
{
{0,0,0,0,0,0,0,0,0,0},
{0,6,6,6,6,6,6,6,6,6},
{0,6,7,7,7,7,7,7,7,6},
{0,6,7,8,8,8,8,8,7,6},
{0,6,7,8,9,9,9,8,7,6},
{0,6,7,8,9,10,9,8,7,6},
{0,6,7,8,9,9,9,8,7,6},
{0,6,7,8,8,8,8,8,7,6},
{0,6,7,7,7,7,7,7,7,6},
{0,6,6,6,6,6,6,6,6,6}
};
int check(int,int,int*);
void dfs();
void CSudoku(int n=40);// 随机生成数独,n越大越难
void display();
void print_all();
int resolve(int mod=ALL);// 解数独
int subgrid(int,int);
void Ins_node(int,int);
void Remove(int);
void Resume(int);
void dfs(int);
void CSudoku(int n)
{
int i,j;
srand(time(0));
do
{
for(i=0;i<9;++i)
{
for(j=0;j<9;++j)
map_exchange[i][j]=0;
j=rand()%9;
map_exchange[i][j]=i+1;
}
}
while(!resolve(ANY));
// 挖窟窿
for(int k=0;k<n;)
{
i=rand()%81;
j=i%9;
i=i/9;
if(map_exchange[i][j]>0)
{
map_exchange[i][j]=0;
++k;
}
}
}
void display()
{
out_stream<<"┏━┯━┯━┳━┯━┯━┳━┯━┯━┓"<<endl;
for(int i=0;i<9;++i)
{
for(int j=0;j<9;++j)
{
if(map_exchange[i][j]>0)
{
if(j%3==0)
out_stream<<"┃ "<<map_exchange[i][j];
else
out_stream<<"│ "<<map_exchange[i][j];
}
else
{
if(j%3==0)
out_stream<<"┃ ";
else
out_stream<<"│ ";
}
}
out_stream<<"┃"<<endl;
if (i!=8)
{
if((i+1)%3==0)
out_stream<<"┣━┿━┿━╋━┿━┿━╋━┿━┿━┫"<<endl;
else
out_stream<<"┠─┼─┼─╂─┼─┼─╂─┼─┼─┨"<<endl;
} }
out_stream<<"┗━┷━┷━┻━┷━┷━┻━┷━┷━┛"<<endl;
}
void print_all()
{
out_stream<<"print storage"<<endl;
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
{
out_stream<<map_exchange[i-1][j-1]<<" ";
if(j%3==0) out_stream<<" ";
}
out_stream<<endl;
if(i%3==0) out_stream<<endl;
}
out_stream<<endl<<endl;
}
int resolve(int mod)
{
smod=mod;
if(mod==ALL)
{
solves=0;
dfs();
return solves;
}
else if(mod==ANY)
{
try
{
dfs();
return 0;
}
catch(int)
{
return 1;
}
}
return 0;
}
int check(int y,int x,int *mark) //求probable[y][x]
{
int i,j,is,js,count=0;
for(i=1;i<=9;++i)
mark[i]=0;
for(i=0;i<9;++i)
mark[map_exchange[y][i]]=1;
for(i=0;i<9;++i)
mark[map_exchange[i][x]]=1;
is=y/3*3;
js=x/3*3;
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
mark[map_exchange[is+i][js+j]]=1;
}
for(i=1;i<=9;++i)
if(mark[i]==0)
count++;
return count;
}
void dfs()
{
int i,j,im=-1,jm,min=10;
int mark[10];
for(i=0;i<9;++i)
{
for(j=0;j<9;++j)
{
if(map_exchange[i][j])
continue;
int c=check(i,j,mark);
if(c==0)
return;
if(c<min)
{
im=i;
jm=j;
min=c;
}
}
}
if(im==-1)
{
if(smod==ALL)
{
printf("No. %d",++solves);
printf("\n");
display();
return;
}
else if(smod==ANY)
{
display();
throw(1);
}
}
check(im,jm,mark);
for(i=1;i<=9;++i)
{
if(mark[i]==0)
{
map_exchange[im][jm]=i;
dfs();
}
}
map_exchange[im][jm]=0;
}
int subgrid(int i,int j)
{
i--; j--;
return (i/3)*3+(j/3+1);
}
void Ins_node(int c,int cnt)
{
U[D[c]]=cnt;
D[cnt]=D[c];
U[cnt]=c;
D[c]=cnt;
S[c]++;
nCol[cnt]=c;
}
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[nCol[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])
{
U[D[j]]=D[U[j]]=j;
S[nCol[j]]++;
}
L[R[c]]=R[L[c]]=c;
}
void dfs(int k)
{
if (k>81)
{
cout<<SCORE<<endl;
if (SCORE>best) best=SCORE;
return;
}
int c,minnum=INT_MAX;
for (int i=R[0];i!=0;i=R[i])
{
if (!S[i]) return;
if (S[i]<minnum)
{
minnum=S[i];
c=i;
}
}
Remove(c);
for (int i=D[c];i!=c;i=D[i])
{
int tmp=nRow[i];
SCORE=SCORE+(tmp%10)*(score[tmp/100][(tmp/10)%10]);
for (int j=R[i];j!=i;j=R[j])
Remove(nCol[j]);
dfs(k+1);
SCORE=SCORE-(tmp%10)*(score[tmp/100][(tmp/10)%10]);
for (int j=L[i];j!=i;j=L[j])
Resume(nCol[j]);
}
Resume(c);
}
int main()
{
int blanks;
out_stream.open("d:\\c++\\数独12\\question\\question474.txt");
cout<<"请输入blanks值"<<endl;
cin>>blanks;
CSudoku (blanks);
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
map[i][j]=map_exchange[i-1][j-1];
display();
resolve(ALL);
out_stream.close();
freopen("d:\\c++\\数独12\\question\\question475.txt","w",stdout);
/*for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
map[i][j]=data1[i-1][j-1];*/
for (int i=0;i<=81*4;i++)
{
S[i]=0;
L[i]=i-1; R[i]=i+1;
U[i]=D[i]=i;
nCol[i]=0;
}
L[0]=81*4; R[81*4]=0;
cnt=81*4;
for (int i=1;i<=9;i++)
for (int j=1;j<=9;j++)
{
if (map[i][j])
{
int k=map[i][j];
for (int u=1;u<=4;u++)
{
L[cnt+u]=cnt+u-1;
R[cnt+u]=cnt+u+1;
nRow[cnt+u]=100*i+10*j+k;
}
L[cnt+1]=cnt+4; R[cnt+4]=cnt+1;
head[i][j][k]=cnt+1;
Ins_node((i-1)*9+j,cnt+1);
Ins_node(81+(i-1)*9+k,cnt+2);
Ins_node(81*2+(j-1)*9+k,cnt+3);
Ins_node(81*3+(subgrid(i,j)-1)*9+k,cnt+4);
cnt+=4;
}
else
for (int k=1;k<=9;k++)
{
for (int u=1;u<=4;u++)
{
L[cnt+u]=cnt+u-1;
R[cnt+u]=cnt+u+1;
nRow[cnt+u]=100*i+10*j+k;
}
L[cnt+1]=cnt+4; R[cnt+4]=cnt+1;
head[i][j][k]=cnt+1;
Ins_node((i-1)*9+j,cnt+1);
Ins_node(81+(i-1)*9+k,cnt+2);
Ins_node(81*2+(j-1)*9+k,cnt+3);
Ins_node(81*3+(subgrid(i,j)-1)*9+k,cnt+4);
cnt+=4;
}
}
int k=0;
for (int i=1;i<=9;i++)
for (int j=1;j<=9;j++)
if (map[i][j])
{
k++;
SCORE+=(map[i][j])*score[i][j];
Remove(nCol[head[i][j][map[i][j]]]);
for (int u=R[head[i][j][map[i][j]]];u!=head[i][j][map[i][j]];u=R[u])
Remove(nCol[u]);
}
dfs(k+1);
printf("%d\n",best);
fclose(stdout);
system("pause");
}