QQ及郵箱:1 4 2 3 1 7 3 7 8 3 @qq.com 歡迎吹毛求疵。
/*這一版本實現了簡單技巧的極致應用,但速度並不快*/
//這一版測試,tecnology會刪除一些候選數,explore()又會把這些候選數恢復,這叫不該恢復的恢復了但好像不影響解題,事實上in_vstart_or_v3() 改爲in_v3()就行了有待實證
//神舟測試七天七夜沒出一個錯誤,按經驗1000000個55空格題目肯定都做完了,問題究竟在哪,以後調試。
//50個空 神舟同時跑四個程序,1000000個題花了約36.09h
#include<iostream>
#include<fstream>
#include<vector>
#include<time.h>
#include<cstdlib>
using namespace std;
#define BLANKS 55
#define FAIL 20
int table[9][9],table_for_solve[9][9],solves=0;
struct{
int semaphore[11];//semaphore[10]表示存儲值
int probable;
int semaphore_explore_recover[10];
int probable_explore_recover;
int explore[10];//每個節點node都可能被用來作爲探索節點,探索時從該節點可能取值的數字(1--9)從小到大依次探索,當一個節點所有取值探索過後都出現錯誤(即該節點不能去任何值)這表明這個探索節點不能取任何值是上一步的錯誤造成的,應該回溯進一步往前恢復。而要判斷該探索節點任何值都不能取就必須設一個長度爲9的數組,如果數組的每個元素都爲0表示每個取值探索過後都不成功,即需要進一步往前回溯。
} node[10][10];
int finished=0,op;
ofstream out_stream;
vector<int> v1;
vector<vector<int>> v2,success,vstart;
vector<vector<vector<int>>> v3;
typedef struct {
int row;
int col;
int probable;
} sign;
sign min_probable_node={{0},{0},{10}};
int room_subscript[2]={0},semaphore[10]={0};//room_subscript[0]存某個宮的行起始號,room_subscript[1]存某宮的列起始號,semaphore[0]存儲node[row][col].semaphore[1]~node[row][col].semaphore.semaphore[9]中不爲0的個數,後面的依次存入不爲0的k值,有幾個k值不爲0就存幾個k值。
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]);
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) out_stream<<endl;
for(int j=1;j<=9;j++)
{
if(j%3==1) out_stream<<" ";
out_stream<<table[i-1][j-1];
}
out_stream<<endl;
}
out_stream<<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 room(int row,int col)
{
return((row-1)/3*3+1+(col-1)/3);
}
int* room(int k)
{
room_subscript[0]=(k-1)/3*3+1;
room_subscript[1]=(k-room_subscript[0])*3+1;
return (room_subscript);
}
void fills_up()
{
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
{
for(int k=1;k<=9;k++)
{
node[i][j].semaphore[k]=1;
node[i][j].semaphore_explore_recover[k]=0;
node[i][j].explore[k]=0;
}
node[i][j].semaphore[10]=0;
node[i][j].probable=9;
node[i][j].probable_explore_recover=0;
}
}
vector<vector<int>> subtraction(int row,int col)
{
finished++;
if(finished==81) return success;
vector<vector<int>> temp;
for(int j=1;j<=9;j++)
if(node[row][j].semaphore[node[row][col].semaphore[10]]==1 && node[row][j].probable!=0)
{
node[row][j].semaphore[node[row][col].semaphore[10]]=0; //把節點中不能填的點排除
node[row][j].probable-=1; //probable即可能填的數目減1
if(node[row][j].probable==1)
{
for(int k=1;k<=9;k++)
if(node[row][j].semaphore[k]==1)
{
for(int m=1;m<=9;m++)
if(k==node[row][m].semaphore[10] && m!=j)
{
v1.push_back(row);
v1.push_back(j);
v1.push_back(0);
v1.push_back(100);
v2.push_back(v1);
v1.clear();
return v2;
}
for(int m=1;m<=9;m++)
if(k==node[m][j].semaphore[10] && m!=row)
{
v1.push_back(row);
v1.push_back(j);
v1.push_back(0);
v1.push_back(100);
v2.push_back(v1);
v1.clear();
return v2;
}
for(int m=(row-1)/3*3+1;m<=(row-1)/3*3+3;m++)
for(int n=(j-1)/3*3+1;n<=(j-1)/3*3+3;n++)
if(k==node[m][n].semaphore[10] && !(m==row && n==j))
{
v1.push_back(row);
v1.push_back(j);
v1.push_back(0);
v1.push_back(100);
v2.push_back(v1);
v1.clear();
return v2;
}
node[row][j].semaphore[10]=k;
node[row][j].semaphore[k]=0;
node[row][j].probable=0;
v1.push_back(row);
v1.push_back(j);
v1.push_back(node[row][j].semaphore[10]);
v1.push_back(10);
v2.push_back(v1);
v1.clear();
temp=subtraction(row,j);
if(temp==success) return success;
if(temp[v2.size()-1][3]>30 && temp[v2.size()-1][3]!=400 )
goto loop;
}
}
}
for(int i=1;i<=9;i++)
if(node[i][col].semaphore[node[row][col].semaphore[10]]==1 && node[i][col].probable!=0)
{
node[i][col].semaphore[node[row][col].semaphore[10]]=0; //把節點中不能填的點排除
node[i][col].probable-=1; //probable即可能填的數目減1
if(node[i][col].probable==1)
{
for(int k=1;k<=9;k++)
if(node[i][col].semaphore[k]==1)
{
for(int m=1;m<=9;m++)
if(k==node[i][m].semaphore[10] && m!=col)
{
v1.push_back(i);
v1.push_back(col);
v1.push_back(0);
v1.push_back(200);
v2.push_back(v1);
v1.clear();
return v2;
}
for(int m=1;m<=9;m++)
if(k==node[m][col].semaphore[10] && m!=i)
{
v1.push_back(i);
v1.push_back(col);
v1.push_back(0);
v1.push_back(200);
v2.push_back(v1);
v1.clear();
return v2;
}
for(int m=(i-1)/3*3+1;m<=(i-1)/3*3+3;m++)
for(int n=(col-1)/3*3+1;n<=(col-1)/3*3+3;n++)
if(k==node[m][n].semaphore[10] && !(m==i && n==col))
{
v1.push_back(i);
v1.push_back(col);
v1.push_back(0);
v1.push_back(200);
v2.push_back(v1);
v1.clear();
return v2;
}
node[i][col].semaphore[10]=k;
node[i][col].semaphore[k]=0;
node[i][col].probable=0;
v1.push_back(i);
v1.push_back(col);
v1.push_back(k);
v1.push_back(20);
v2.push_back(v1);
v1.clear();
temp=subtraction(i,col);
if(temp==success) return success;
if(temp[v2.size()-1][3]>30 && temp[v2.size()-1][3]!=400 )
goto loop;
}
}
}
for(int i=(row-1)/3*3+1;i<=(row-1)/3*3+3;i++)
for(int j=(col-1)/3*3+1 ;j<=(col-1)/3*3+3;j++)
if(node[i][j].semaphore[node[row][col].semaphore[10]]==1 && node[i][j].probable!=0)
{
node[i][j].semaphore[node[row][col].semaphore[10]]=0; //把節點中不能填的點排除
node[i][j].probable-=1; //probable即可能填的數目減1
if(node[i][j].probable==1)
{
for(int k=1;k<=9;k++)
if(node[i][j].semaphore[k]==1)
{
for(int m=1;m<=9;m++)
{
if(node[i][m].semaphore[10]==k && m!=j)
{
v1.push_back(i);
v1.push_back(j);
v1.push_back(0);
v1.push_back(300);
v2.push_back(v1);
v1.clear();
return v2;
}
}
for(int m=1;m<=9;m++)
{
if(node[m][j].semaphore[10]==k && m!=i)
{
v1.push_back(i);
v1.push_back(j);
v1.push_back(0);
v1.push_back(300);
v2.push_back(v1);
v1.clear();
return v2;
}
}
for(int m=(row-1)/3*3+1;m<=(row-1)/3*3+3;m++)
for( int n=(col-1)/3*3+1;n<=(col-1)/3*3+3;n++)
{
if(k==node[m][n].semaphore[10] && !(m==i && n==j))
{
v1.push_back(i);
v1.push_back(j);
v1.push_back(0);
v1.push_back(300);
v2.push_back(v1);
v1.clear();
return v2;
}
}
node[i][j].semaphore[10]=k;
node[i][j].semaphore[k]=0;
node[i][j].probable=0;
v1.push_back(i);
v1.push_back(j);
v1.push_back(k);
v1.push_back(30);
v2.push_back(v1);
v1.clear();
temp=subtraction(i,j);
if(temp==success) return success;
if(temp[v2.size()-1][3]>30 && temp[v2.size()-1][3]!=400 )
goto loop;
}
}
}
v1.push_back(row);
v1.push_back(col);
v1.push_back(1);
v1.push_back(400);
v2.push_back(v1);
v1.clear();
loop: return v2;
}
bool in_vstart_or_v3(int row,int col,int number)
{
/*for(int i=vstart.size()-1;i>=0;i--)
if(vstart[i][0]==row && vstart[i][1]==col && vstart[i][2]==number)
return (true);*/
for(int i=v3.size()-1;i>=0;i--)
for(int j=v3[i].size()-1;j>=0;j--)
if(v3[i][j][0]==row && v3[i][j][1]==col && v3[i][j][2]==number)
return (true);
return (false);
}
bool row_col_relation_have_the_number(int row,int col,int number)
{
for(int j=1;j<=9;j++)
if(node[row][j].semaphore[10]==number )
if(in_vstart_or_v3(row,j,number)) //調試後發現的 (row,j)到底要不要恢復 即node[row][j].semaphore[number]要不要從0變爲1首先看(row,j)所在行列區塊有沒有填number.說明node[row][j].semaphore[numer]是剛剛從1變爲0的,要恢復。如果發現(row,j)所在行列區塊已經填了number,那就要判斷這個number是何時填的:1.在vstart或v3中填的,說明這個number不但填得早,而且很早前node[row][j].semaphore[number]一定會被減掉,(要知道此刻我正恢復的是v2),這種情況說明v2是沒減它的不恢復
2.在v2中填的,這裏要特別注意:現在的確是在恢復v2但如果是在v2前面填的number,在調用add(v2)時v2_transcript又沒和填number的v1匹配,這說明v2很早時填number會壓入一個v1進v2但此時填的number來不及影響你(減你)就調用別的subtraction去了,因爲它沒減你add(v2)也沒讓你們匹配,這就是add(v2)的精確。綜述只要恢復v2時number不出現在vstart和v3中,就一定要恢復。
return (true);
for(int i=1;i<=9;i++)
if(node[i][col].semaphore[10]==number)
if(in_vstart_or_v3(i,col,number))
return (true);
for(int i=(row-1)/3*3+1;i<=(row-1)/3*3+3;i++)
for( int j=(col-1)/3*3+1;j<=(col-1)/3*3+3;j++)
if(node[i][j].semaphore[10]==number)
if(in_vstart_or_v3(i,j,number))
return (true);
return (false);
}
void add(int row1,int col1,int row2,int col2,int storage,int semaphore)//semaphore的值爲100,200,300,400 表示從四個方向上恢復
{
finished--;
node[row1][col1].semaphore[storage]=1;
node[row1][col1].probable+=1; //node[row][col].storage的值最後變回0,下面恢復三個區域要用到這個值。
node[row1][col1].semaphore[10]=0;
switch(semaphore)
{
case 100: for(int j=col2;j>=1;j--)
if(node[row1][j].semaphore[storage]==0 && node[row1][j].probable!=0 && !row_col_relation_have_the_number(row1,j,storage))//這一行最後面那個函數是調試後打的補丁 用處是不該恢復的不恢復
{
node[row1][j].semaphore[storage]=1;
node[row1][j].probable+=1;
} break;
case 200: for(int i=row2;i>=1;i--)
if(node[i][col2].semaphore[storage]==0 && node[i][col2].probable!=0 && !row_col_relation_have_the_number(i,col2,storage))
{
node[i][col2].semaphore[storage]=1;
node[i][col2].probable+=1;
}
for(int j=9;j>=1;j--)
if(node[row1][j].semaphore[storage]==0 && node[row1][j].probable!=0 && !row_col_relation_have_the_number(row1,j,storage))
{
node[row1][j].semaphore[storage]=1;
node[row1][j].probable+=1;
} break;
case 300: for(int j=col2;j>=(col2-1)/3*3+1;j--)
if(node[row2][j].semaphore[storage]==0 && node[row2][j].probable!=0 && !row_col_relation_have_the_number(row2,j,storage))
{
node[row2][j].semaphore[storage]=1;
node[row2][j].probable+=1;
}
for(int i=row2-1;i>=(row2-1)/3*3+1;i--)
for(int j=(col2-1)/3*3+3;j>=(col2-1)/3*3+1;j--)
if(node[i][j].semaphore[storage]==0 && node[i][j].probable!=0 && !row_col_relation_have_the_number(i,j,storage))
{
node[i][j].semaphore[storage]=1;
node[i][j].probable+=1;
}
for(int i=9;i>=1;i--)
if(node[i][col1].semaphore[storage]==0 && node[i][col1].probable!=0 && !row_col_relation_have_the_number(i,col1,storage))
{
node[i][col1].semaphore[storage]=1;
node[i][col1].probable+=1;
}
for(int j=9;j>=1;j--)
if(node[row1][j].semaphore[storage]==0 && node[row1][j].probable!=0 && !row_col_relation_have_the_number(row1,j,storage))
{
node[row1][j].semaphore[storage]=1;
node[row1][j].probable+=1;
}
break;
case 400: for(int i=(row2-1)/3*3+3;i>=(row2-1)/3*3+1;i--)
for(int j=(col2-1)/3*3+3;j>=(col2-1)/3*3+1;j--)
if(node[i][j].semaphore[storage]==0 && node[i][j].probable!=0 && !row_col_relation_have_the_number(i,j,storage))
{
node[i][j].semaphore[storage]=1;
node[i][j].probable+=1;
}
for(int i=9;i>=1;i--)
if(node[i][col1].semaphore[storage]==0 && node[i][col1].probable!=0 && !row_col_relation_have_the_number(i,col1,storage))
{
node[i][col1].semaphore[storage]=1;
node[i][col1].probable+=1;
}
for(int j=9;j>=1;j--)
if(node[row1][j].semaphore[storage]==0 && node[row1][j].probable!=0 && !row_col_relation_have_the_number(row1,j,storage))
{
node[row1][j].semaphore[storage]=1;
node[row1][j].probable+=1;
}
break;
}
if(node[row1][col1].probable_explore_recover!=0)
{
for(int i=1;i<=9;i++)
node[row1][col1].semaphore[i]=node[row1][col1].semaphore_explore_recover[i];
node[row1][col1].probable=node[row1][col1].probable_explore_recover;
for(int i=1;i<=9;i++) //調試發現的 後來加上
node[row1][col1].semaphore_explore_recover[i]=0;
node[row1][col1].probable_explore_recover=0; //調試發現的,後來加上
min_probable_node.row=row1;
min_probable_node.col=col1;
min_probable_node.probable=node[row1][col1].probable;
}
}
void addv2(vector<vector<int>> & v2)
{
vector<vector<int>> v2_transcript;
switch(v2[v2.size()-1][3])
{
case 100:
case 200:
case 300:
case 400:
v2_transcript.push_back(v2[v2.size()-1]);
v2.pop_back();
}
for( int i=v2.size()-1;i>=0;i--)
{
if(v2[i][3]==400)
{
v2_transcript.push_back(v2[i]);
v2.pop_back();
continue;
}
if(v2_transcript[v2_transcript.size()-1][3]==400 )
{
add(v2[i][0],v2[i][1],v2[i][0],v2[i][1],v2[i][2],400);
if(v2_transcript.size()==1)
{
v2_transcript.pop_back();
v2_transcript.push_back(v2[v2.size()-1]);
v2.pop_back();
}
else
{
v2.pop_back();
v2_transcript.pop_back();
}
continue;
}
if(v2_transcript[0][3]==100 || v2_transcript[0][3]==200 || v2_transcript[0][3]==300)
{
add(v2[i][0],v2[i][1],v2_transcript[0][0],v2_transcript[0][1],v2[i][2],v2_transcript[0][3]);
v2_transcript.pop_back();
v2_transcript.push_back(v2[v2.size()-1]);
v2.pop_back();
continue;
}
if(v2_transcript[0][3]==10 || v2_transcript[0][3]==20 || v2_transcript[0][3]==30)
{
add(v2[i][0],v2[i][1],v2_transcript[0][0],v2_transcript[0][1],v2[i][2],v2_transcript[0][3]*10);
v2_transcript.pop_back();
v2_transcript.push_back(v2[v2.size()-1]);
v2.pop_back();
continue;
}
}//for
}
void print_all()
{
out_stream<<"print storage"<<endl;
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
{
out_stream<<node[i][j].semaphore[10]<<" ";
if(j%3==0) out_stream<<" ";
}
out_stream<<endl;
if(i%3==0) out_stream<<endl;
}
out_stream<<endl<<endl;
}
void explore( )
{
int row,col,probable;
probable=10;
for(int i=9;i>=1;i--)
{
for(int j=9 ;j>=1;j--)
{
if(probable>=node[i][j].probable && node[i][j].probable!=0 )
{ probable=node[i][j].probable;
row=i;
col=j;
}
}
}
min_probable_node.row=row;
min_probable_node.col=col;
min_probable_node.probable=probable;
for(int k=1;k<=9;k++)
{
if(node[min_probable_node.row][min_probable_node.col].semaphore[k]==1)
{
for(int r=1;r<=9;r++)
if(node[min_probable_node.row][r].semaphore[10]==k )
goto loop;
for(int r=1;r<=9;r++)
if(node[r][min_probable_node.col].semaphore[10]==k )
goto loop;
for( int i=(min_probable_node.row-1)/3*3+1;i<=(min_probable_node.row-1)/3*3+3;i++)
for(int j=(min_probable_node.col-1)/3*3+1;j<=(min_probable_node.col-1)/3*3+3;j++)
if(node[i][j].semaphore[10]==k)
goto loop;
for(int r=1;r<=9;r++)
node[min_probable_node.row][min_probable_node.col].semaphore_explore_recover[r]=node[min_probable_node.row][min_probable_node.col].semaphore[r];
node[min_probable_node.row][min_probable_node.col].probable_explore_recover=node[min_probable_node.row][min_probable_node.col].probable;
for(int r=1;r<=9;r++)
node[min_probable_node.row][min_probable_node.col].semaphore[r]=0;
node[min_probable_node.row][min_probable_node.col].probable=0;
node[min_probable_node.row][min_probable_node.col].semaphore[10]=k;
v1.push_back(min_probable_node.row);
v1.push_back(min_probable_node.col);
v1.push_back(node[min_probable_node.row][min_probable_node.col].semaphore[10]);
v1.push_back(0);
v2.push_back(v1);
v1.clear();
node[min_probable_node.row][min_probable_node.col].explore[k]=1;
if(subtraction(min_probable_node.row,min_probable_node.col)==success)
;
else if(v2[v2.size()-1][3]>30 && v2[v2.size()-1][3]!=400)
{
addv2(v2);
v2.clear();
node[min_probable_node.row][min_probable_node.col].explore[k]=0;
}
else
{
v3.push_back(v2);
v2.clear();
explore();
}
}
loop: ;
}
int sum=0;
for(int k=1;k<=9;k++)
sum+=node[min_probable_node.row][min_probable_node.col].explore[k];
if(sum==0)
{
node[v3[v3.size()-1][0][0]][v3[v3.size()-1][0][1]].explore[v3[v3.size()-1][0][2]]=0;
addv2(v3[v3.size()-1]);
v3.pop_back();
}
}
int fun( int array[10])
{
int i,j;
for(i=1;i<=8;i++)
{
if(*(array+i)==0) continue;
for(j=i+1;j<=9;j++)
if(*(array+i)==*(array+j)) return 0;
}
return 1;
}
int test()
{
int sum=0,i,j,a[10];
for(int i=1;i<=9;i++)
{
sum=0;
for(int j=1;j<=9;j++)
{ sum+=node[i][j].semaphore[10]; a[j]=node[i][j].semaphore[10];}
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
if(!fun(a)) return 0;
}
for( j=1;j<=9;j++)
{
sum=0;
for(i=1;i<=9;i++)
{ sum+=node[i][j].semaphore[10]; a[i]=node[i][j].semaphore[10];}
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
if(!fun(a)) return 0;
}
for(i=1;i<=9;i++)
{
sum=0;
int row_start,col_start,sub=1;
row_start=(i-1)/3*3+1; col_start=(i-1)%3*3+1;
for(int m=row_start;m<=row_start+2;m++)
for(int n=col_start;n<=col_start+2;n++)
{ sum+=node[m][n].semaphore[10]; a[sub++]=node[m][n].semaphore[10];}
if(sum!=45) { cout<<"wrong"<<endl; return 0;}
if(!fun(a)) return 0;
}
return 1;
}
int main()
{
int information_number=0;
long time1;
out_stream.open("d:\\my documents\\visual studio 2010\\projects\\測試算法\\測試(v3)_(no_tec_rec).txt");
time1=clock();
srand(time(0));
for(op=1;op<=500000;op++)
{
create_gameover();
while(!create_game(BLANKS))
create_gameover();
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
if(table[i-1][j-1]!=0)
{
v1.push_back(i);
v1.push_back(j);
v1.push_back(table[i-1][j-1]);
v2.push_back(v1);
v1.clear();
}
information_number=v2.size();
fills_up();
for(int i=0;i<information_number;i++)
{
for(int k=1;k<=9;k++)
node[v2[i][0]][v2[i][1]].semaphore[k]=0;
node[v2[i][0]][v2[i][1]].probable=0;
node[v2[i][0]][v2[i][1]].semaphore[10]=v2[i][2];
}
vector<vector<int>> v2_temporary;
for(int i=0;i<information_number;i++)
{
v2_temporary=subtraction(v2[i][0],v2[i][1]);
if(v2_temporary==success)
break;
if(v2_temporary[v2.size()-1][3]==400) continue;
if(v2_temporary[v2.size()-1][3]==100 || v2_temporary[v2.size()-1][3]==200 ||v2_temporary[v2.size()-1][3]==300)
{
cout<<"數組題目設計錯誤"<<endl;
}
}
v2.clear();
if(finished==81 && test())
{
v2.clear(); v3.clear();v1.clear(); vstart.clear(); finished=0;
continue;
}
explore();
if(test()) ;
else { out_stream<<"測試第"<<op<<"個題目失敗"<<endl; print_all(1); print_all();}
v2.clear(); v3.clear();v1.clear(); vstart.clear(); finished=0;
}
time1=clock()-time1;
out_stream<<"耗時"<<time1/1000<<"秒"<<time1%1000<<"毫秒"<<endl;
out_stream.close();
}