测试pure dlx(best)
来源:互联网 发布:为什么淘宝商品被下架 编辑:程序博客网 时间:2024/06/13 22:59
原链接:http://blog.sina.com.cn/s/blog_51cea4040100gxn1.html
//在神舟上测试了19个多小时,测试通过
//BLANKS==55 2.687ms解决一个数独题目。BLANKS==50 186us解决一个数独题目。(神舟测试)这项速度测试的代码没有贴出,把下面代码稍做改动就行。
#include<cstdlib>
#include<iostream>
#include<time.h>
using namespace std;
#define BLANKS 55
#define FAIL 20
int table[9][9],table_for_solve[9][9],solves=0;
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];
void shuffle(int arr[], int n);
bool test(int x, int y, int v);
bool put(int line, int index);
bool put_line(int line);
void DFS();
int check(int y,int x,int *mark) ; //求probable[y][x] 并且mark[]中为0的元素说明可以试探
int solve22();
bool create_game(int blanks);
void create_gameover();
void print_all(int k); //输出到文件
void copy(int a[9][9],int b[9][9]);
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]);
void shuffle(int arr[], int n)
{
int tmp, rd;
for(int i = 0; i < n; i++)
{
rd = rand() % 9;
tmp = arr[rd];
arr[rd] = arr[i];
arr[i] = tmp;
}
}
bool test(int x, int y, int v)
{
int _x = x / 3 * 3;
int _y = y / 3 * 3;
for(int i = _x; i < _x + 3; i++) //测试3 * 3矩阵内是否有重复的数
{
for(int j = _y; j < _y + 3; j++)
{
if(table[i][j] == v)
{
return false;
}
}
}
for(int i = 0; i < 9; i++) //测试横向、纵向是否有重复的数
{
if(table[x][i] == v || table[i][y] == v)
return false;
}
return true;
}
bool put(int line, int index)
{
if(index > 8)
return true;
int num[] = {1,2,3,4,5,6,7,8,9};
//打乱当前准备写入数字的前后顺序
shuffle(num, 9);
for(int i = 0; i < 9; i++)
//测试数字是否允许填入当前方格
if( test(line, index, num[i]) == true )
{
table[line][index] = num[i];
//填入成功则处理下一个方格
if( put(line, index + 1) == true )
{
return true;
}
}
table[line][index] = 0; //失败后复位
return false;
}
bool put_line(int line)
{
if(line > 8)
return true;
if( put(line, 0) == true )
//当前一行添入完成后,进入下一行再重复处理。
if( put_line(line + 1) == true )
return true;
for(int i = 0; i < 9; i++)
table[line][i] = 0;
return false;
}
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(table_for_solve[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)
{
solves++;
if(solves==2)
throw(1); //如果解法不唯一,不会等到所有解都出来才结束运行, 保留下面的return又能确定是不是只有唯一解。
return;
}
check(im,jm,mark);
for(i=1;i<=9;++i)
if(mark[i]==0)
{
table_for_solve[im][jm]=i;
DFS();
}
table_for_solve[im][jm]=0;
}
int solve22()
{
try
{
DFS();
solves=0; //调试后发现
return(1);
}
catch(int)
{
solves=0; //调试后发现,solves是全局变量,以后solves越来越大永远不可能等于2
return(2);
}
}
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[table_for_solve[y][i]]=1;
for(i=0;i<9;++i)
mark[table_for_solve[i][x]]=1;
is=y/3*3;
js=x/3*3;
for(i=0;i<3;++i)
for(j=0;j<3;++j)
mark[table_for_solve[is+i][js+j]]=1;
for(i=1;i<=9;++i)
if(mark[i]==0)
count++;
return count;
}
bool create_game(int blanks)
{
int i,k,row,col,tmp;
for( i=1;i<=blanks;i++)
{
int num=0;
do
{
do
{
k=rand()%81;
row=k/9;
col=k-9*row;
tmp=table[row][col];
}while(tmp==0);
table[row][col]=0;
copy(table_for_solve,table);
num++;
if(num==FAIL) return(false);
}while((solve22()==2)? table[row][col]=tmp : 0);
}
if(i==blanks+1) return (true);
}
void create_gameover()
{
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
table[i][j]=0;
for(int i = 0; i < 9; i++)
table[0][i] = i + 1;
shuffle(table[0], 9);
//从第二行开始添入数字
while(!put_line(1)) ;
}
void print_all(int k)
{
for(int i=1;i<=9;i++)
{
if(i%3==1) cout<<endl;
for(int j=1;j<=9;j++)
{
if(j%3==1) cout<<" ";
cout<<table[i-1][j-1];
}
cout<<endl;
}
cout<<endl<<endl;
}
void copy(int a[9][9],int b[9][9])
{
for(int i=0;i<=8;i++)
for(int j=0;j<=8;j++)
a[i][j]=b[i][j];
}
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);
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);
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\\question472.txt","w",stdout);
int op=1;
srand(time(0));
long time1,time2;
time1=clock();
while (op<=1000000)
{
if (op==1000001) break;
create_gameover();
while(!create_game(BLANKS))
create_gameover();
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
map[i][j]=table[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++;
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);
if(test()) ;
else cout<<op<<endl;
op++;
}
time2=clock();
cout<<time2-time1<<"ms"<<endl;
fclose(stdout);
}
- 测试pure dlx(best)
- 测试 pure dlx(one form)
- 测试dfs dlx(测试不通过)求助:
- 测试dlx 数组
- HUST 1017(DLX)
- DLX
- DLX
- DLX
- 性能测试工具, Pure Software vs Appliance
- ccy测试dlx 模块化与全局变量
- DLX算法及应用(一)DLX模板+解数独
- DLX(n皇后)spoj1771
- hdu2295(DLX重复覆盖)
- 什么叫pure function(纯函数)
- poj 2676 dfs/DLX(数独)
- DLX(只能覆盖一次)zoj3209
- HDU 2295 Radar(重复覆盖,DLX)
- HDU 3957 Street Fighter(DLX搜索)
- 【J2ME资料汇总】48个推荐资料+40个经典源码——下载目录
- js限制文本域输入长度
- 对Visual Assist x的设置 VS2010工程重新打开时 一直在加载而打不开
- ASP.NET Session的七点认识
- 协议 委托
- 测试pure dlx(best)
- 16道嵌入式C语言面试题
- 网络安全热门资料 精品工具——下载目录
- MySQL 1045登录失败
- POJ 1161 WALLS
- 今日总结10_31
- 原来文件输入也能用STL
- 字符串模版替换的方法MessageFormat.format(-----)
- 【资料目录收藏】.NET开发必看资料53个+经典源码77个