s(vstart_and_v3)_(e_tec)_(no_tec_rec)
QQ及邮箱:1 4 2 3 1 7 3 7 8 3 @qq.com欢迎吹毛求疵。
/*这一版本实现了简单技巧的极致应用,但速度并不快*/
#include<iostream>
#include<fstream>
#include<vector>
#include<time.h>
#include<cstdlib>
using namespace std;
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;
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 row_technology(int,int);
void array_technology(int,int);
void room_technology(int,int);
int room(int row,int col)
{
return((row-1)/3*3+1+(col-1)/3);
}
int room(int row1,int col1,int row2,int col2)//返回值为1表示横族关系,2表示纵族关系,0表示没有族的关系
{
int k1=room(row1,col1);
int k2=room(row2,col2);
if(k1-k2==3 || k1-k2==-3 || k1-k2==6 || k1-k2==-6)
return (2);
else if(k1<=3) if(k2<=3) return (1);
else if(k1<=6) if(k2<=6) return (1);
else if(k1<=9) if(k2<=9) return (1);
else return(0);
}
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;
}
}
void subtraction(int row,int col,int storage)
{
finished++;
for(int j=1;j<=9;j++)
if(node[row][j].semaphore[storage]==1)
{
node[row][j].semaphore[storage]=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)
{
out_stream<<"唯一数:"<<char(row-1+'A')<<j<<"应填"<<k<<"。"<<endl;
cout<<"唯一数:"<<char(row-1+'A')<<j<<"应填"<<k<<"。"<<endl;
node[row][j].semaphore[10]=k;
node[row][j].semaphore[k]=0;
node[row][j].probable=0;
subtraction(row,j,k);
}
}
}
for(int i=1;i<=9;i++)
if(node[i][col].semaphore[storage]==1)
{
node[i][col].semaphore[storage]=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)
{
out_stream<<"唯一数:"<<char(i-1+'A')<<col<<"应填"<<k<<"。"<<endl;
cout<<"唯一数:"<<char(i-1+'A')<<col<<"应填"<<k<<"。"<<endl;
node[i][col].semaphore[10]=k;
node[i][col].semaphore[k]=0;
node[i][col].probable=0;
subtraction(i,col,k);
}
}
}
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[storage]==1)
{
node[i][j].semaphore[storage]=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)
{
out_stream<<"唯一数:"<<char(i-1+'A')<<j<<"应填"<<k<<"。"<<endl;
cout<<"唯一数:"<<char(i-1+'A')<<j<<"应填"<<k<<"。"<<endl;
node[i][j].semaphore[10]=k;
node[i][j].semaphore[k]=0;
node[i][j].probable=0;
subtraction(i,j,k);
}
}
}
}
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;
}
void call_subtraction(int row,int col,int k)//k=1表示技术用,k=0表示回溯用
{
if(k==1)
{
for(int k=1;k<=9;k++)
if(node[row][col].semaphore[k]==1)
{
out_stream<<"唯一数:"<<char(row-1+'A')<<col<<"应填"<<k<<"。"<<endl;
cout<<"唯一数:"<<char(row-1+'A')<<col<<"应填"<<k<<"。"<<endl;
node[row][col].semaphore[k]=0;
node[row][col].semaphore[10]=k;
node[row][col].probable=0;
subtraction(row,col,k);
}
}
else if(k==0)
{
for(int k=1;k<=9;k++)
if(node[row][col].semaphore[k]==1)
{
node[row][col].semaphore[k]=0;
node[row][col].semaphore[10]=k;
node[row][col].probable=0;
subtraction(row,col);
}
}
}
int* probable_num(int row,int col)
{
int sum=0;
for(int k=1;k<=9;k++)
if(node[row][col].semaphore[k]!=0)
{
sum++;
semaphore[sum]=k;
}
semaphore[0]=sum;
return (semaphore);
}
void row_technology(int row,int m)//m表示候选数
{
int col;
int *p=new int[10];
int sum=0;
for(col=1;col<=9;col++)
if(node[row][col].semaphore[m]==1)
p[sum++]=col;
if(sum==1)//非回溯
{
int* a=new int[10];//p[1]到p[9]如果为1说明会被减去
for(int i=1;i<=9;i++)
a[i]=0;
for(int k=1;k<=m-1;k++)
if(node[row][p[0]].semaphore[k]==1)
{
a[k]=1;//此时不对要减去的候选数进行操作,把它后延是因为后面还有更诱人的subtraction操作,让它先进行则更快
out_stream<<"行列区互相影响候选数删减法:"<<char(row-1+'A')<<p[0]<<"应删"<<k<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(row-1+'A')<<p[0]<<"应删"<<k<<"。"<<endl;
}
for(int k=m+1;k<=9;k++)
if(node[row][p[0]].semaphore[k]==1)
{
a[k]=1;//此时不对要减去的候选数进行操作,把它后延是因为后面还有更诱人的subtraction操作,让它先进行则更快
out_stream<<"行列区互相影响候选数删减法:"<<char(row-1+'A')<<p[0]<<"应删"<<k<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(row-1+'A')<<p[0]<<"应删"<<k<<"。"<<endl;
}
for(col=1;col<=9;col++)
node[row][p[0]].semaphore[col]=0;
node[row][p[0]].probable=0;
node[row][p[0]].semaphore[10]=m;
out_stream<<"唯一数:"<<char(row-1+'A')<<p[0]<<"应填"<<m<<"。"<<endl;
cout<<"唯一数:"<<char(row-1+'A')<<p[0]<<"应填"<<m<<"。"<<endl;
subtraction(row,p[0],m);
for(int k=1;k<=9;k++)
if(a[k]==1)
{
row_technology(row,k);
array_technology(p[0],k);
room_technology(room(row,p[0]),k);
}
delete[] a;
}
else if (sum==2)//非回溯
{
if(room(row,p[0])==room(row,p[1]))
{
int* a=new int[5];
a[0]=0;a[1]=0;a[2]=0;a[3]=0;a[4]=0;//a[0],a[1],a[2]对应三列,如为1表示相应的列候选数v[i]肯定被删减,a[3],a[4]对应两行,这两空直接填入删减v[i]候选数的行号,如果没有行被删减v[i]候选数,a[3],a[4]则都为0
int k1=room(room(row,p[0]))[0];
int k2=room(room(row,p[0]))[1];
for(int i=k1;i<=row-1;i++)
for(int j=k2;j<=k2+2;j++)
if(node[i][j].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
node[i][j].semaphore[m]=0;
node[i][j].probable--;
if(node[i][j].probable==1)
call_subtraction(i,j,1);//
a[j-k2]=1;
if(a[3]==0) a[3]=i;
else if(a[3]!=i) a[4]=i;
}
for(int i=row+1;i<=k1+2;i++)
for(int j=k2;j<=k2+2;j++)
if(node[i][j].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
node[i][j].semaphore[m]=0;
node[i][j].probable--;
if(node[i][j].probable==1)
call_subtraction(i,j,1);//
a[j-k2]=1;
if(a[3]==0) a[3]=i;
else if(a[3]!=i) a[4]=i;
}
if(a[0]==1) array_technology(k2,m);
if(a[1]==1) array_technology(k2+1,m);
if(a[2]==1) array_technology(k2+2,m);
if(a[3]!=0) row_technology(a[3],m);
if(a[4]!=0) row_technology(a[4],m);
delete[] a;
}
}
else if (sum==3)//非回溯
{
if(room(row,p[0])==room(row,p[1]) && room(row,p[0])==room(row,p[2]))
{
int* a=new int[5];
a[0]=0;a[1]=0;a[2]=0;a[3]=0;a[4]=0;//a[0],a[1],a[2]对应三列,如为1表示相应的列候选数v[i]肯定被删减,a[3],a[4]对应两行,这两空直接填入删减v[i]候选数的行号,如果没有行被删减v[i]候选数,a[3],a[4]则都为0
int k1=room(room(row,p[0]))[0];
int k2=room(room(row,p[0]))[1];
for(int i=k1;i<=row-1;i++)
for(int j=k2;j<=k2+2;j++)
if(node[i][j].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
node[i][j].semaphore[m]=0;
node[i][j].probable--;
if(node[i][j].probable==1)
call_subtraction(i,j,1);//
a[j-k2]=1;
if(a[3]==0) a[3]=i;
else if(a[3]!=i) a[4]=i;
}
for(int i=row+1;i<=k1+2;i++)
for(int j=k2;j<=k2+2;j++)
if(node[i][j].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
node[i][j].semaphore[m]=0;
node[i][j].probable--;
if(node[i][j].probable==1)
call_subtraction(i,j,1);//
a[j-k2]=1;
if(a[3]==0) a[3]=i;
else if(a[3]!=i) a[4]=i;
}
if(a[0]==1) array_technology(k2,m);
if(a[1]==1) array_technology(k2+1,m);
if(a[2]==1) array_technology(k2+2,m);
if(a[3]!=0) row_technology(a[3],m);
if(a[4]!=0) row_technology(a[4],m);
delete[] a;
}
}
delete[] p;
}
void array_technology(int col,int m)//m只能填在行的某一空上 或k只能填在这一列的某一宫上,k表示候选数
{
int row;
int *p=new int[10];
int sum=0;
for(row=1;row<=9;row++)
if(node[row][col].semaphore[m]==1)
p[sum++]=row;
if(sum==1)
{
int* a=new int[10];//p[1]到p[9]如果为1说明会被减去
for(int i=1;i<=9;i++)
a[i]=0;
for(int k=1;k<=m-1;k++)
if(node[p[0]][col].semaphore[k]==1)
{
a[k]=1;//此时不对要减去的候选数进行操作,把它后延是因为后面还有更诱人的subtraction操作,让它先进行则更快
out_stream<<"行列区互相影响候选数删减法:"<<char(p[0]-1+'A')<<col<<"应删"<<k<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(p[0]-1+'A')<<col<<"应删"<<k<<"。"<<endl;
}
for(int k=m+1;k<=9;k++)
if(node[p[0]][col].semaphore[k]==1)
{
a[k]=1;//此时不对要减去的候选数进行操作,把它后延是因为后面还有更诱人的subtraction操作,让它先进行则更快
out_stream<<"行列区互相影响候选数删减法:"<<char(p[0]-1+'A')<<col<<"应删"<<k<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(p[0]-1+'A')<<col<<"应删"<<k<<"。"<<endl;
}
for(row=1;row<=9;row++)
node[p[0]][col].semaphore[row]=0;
node[p[0]][col].probable=0;
node[p[0]][col].semaphore[10]=m;
out_stream<<"唯一数:"<<char(p[0]-1+'A')<<col<<"应填"<<m<<"。"<<endl;
cout<<"唯一数:"<<char(p[0]-1+'A')<<col<<"应填"<<m<<"。"<<endl;
subtraction(p[0],col,m);
for(int k=1;k<=9;k++)
if(a[k]==1)
{
row_technology(p[0],k);
array_technology(col,k);
room_technology(room(p[0],col),k);
}
delete[] a;
}
else if (sum==2)//非回溯
{
if(room(p[0],col)==room(p[1],col))
{
int* a=new int[5];
a[0]=0;a[1]=0;a[2]=0;a[3]=0;a[4]=0;//a[0],a[1],a[2]对应三行,如为1表示相应行的候选数v[i]肯定被删减,a[3],a[4]对应两列,这两空直接填入删减v[i]候选数的列,如果没有列被删减v[i]候选数,a[3],a[4]则都为0
int k1=room(room(p[0],col))[0];
int k2=room(room(p[0],col))[1];
for(int i=k1;i<=k1+2 ;i++)
for(int j=k2;j<=col-1;j++)
if(node[i][j].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
node[i][j].semaphore[m]=0;
node[i][j].probable--;
if(node[i][j].probable==1)
call_subtraction(i,j,1);//
a[i-k1]=1;
if(a[3]==0) a[3]=j;
else if(a[3]!=j) a[4]=j;
}
for(int i=k1;i<=k1+2 ;i++)
for(int j=col+1;j<=k2+2 ;j++)
if(node[i][j].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
node[i][j].semaphore[m]=0;
node[i][j].probable--;
if(node[i][j].probable==1)
call_subtraction(i,j,1);//
a[i-k1]=1;
if(a[3]==0) a[3]=j;
else if(a[3]!=j) a[4]=j;
}
if(a[0]==1) row_technology(k1,m);
if(a[1]==1) row_technology(k1+1,m);
if(a[2]==1) row_technology(k1+2,m);
if(a[3]!=0) array_technology(a[3],m);
if(a[4]!=0) array_technology(a[4],m);
delete[] a;
}
}
else if (sum==3)//非回溯
{
if(room(p[0],col)==room(p[1],col) && room(p[0],col)==room(p[2],col))
{
int* a=new int[5];
a[0]=0;a[1]=0;a[2]=0;a[3]=0;a[4]=0;//a[0],a[1],a[2]对应三行,如为1表示相应行的候选数v[i]肯定被删减,a[3],a[4]对应两列,这两空直接填入删减v[i]候选数的列,如果没有列被删减v[i]候选数,a[3],a[4]则都为0
int k1=room(room(p[0],col))[0];
int k2=room(room(p[0],col))[1];
for(int i=k1;i<=k1+2 ;i++)
for(int j=k2;j<=col-1;j++)
if(node[i][j].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
node[i][j].semaphore[m]=0;
node[i][j].probable--;
if(node[i][j].probable==1)
call_subtraction(i,j,1);//
a[i-k1]=1;
if(a[3]==0) a[3]=j;
else if(a[3]!=j) a[4]=j;
}
for(int i=k1;i<=k1+2 ;i++)
for(int j=col+1;j<=k2+2 ;j++)
if(node[i][j].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(i-1+'A')<<j<<"应删"<<m<<"。"<<endl;
node[i][j].semaphore[m]=0;
node[i][j].probable--;
if(node[i][j].probable==1)
call_subtraction(i,j,1);//
a[i-k1]=1;
if(a[3]==0) a[3]=j;
else if(a[3]!=j) a[4]=j;
}
if(a[0]==1) row_technology(k1,m);
if(a[1]==1) row_technology(k1+1,m);
if(a[2]==1) row_technology(k1+2,m);
if(a[3]!=0) array_technology(a[3],m);
if(a[4]!=0) array_technology(a[4],m);
delete[] a;
}
}
delete[] p;
}
void room_technology(int i,int m)//m只能填在某空上 或 k只能填在宫的某一行(列)上 , i表示room号,j=4表示遍历所有技巧,j=1表示此宫只有一个位置可填某候选数,j=2表示某候选数只能填在宫的某行,j=3表示某候选数只能填在某宫的某列
{
int k1=room(i)[0],k2=room(i)[1];
vector<int> v1;
vector<vector<int>> v2;
int sum=0;
for(int i=k1;i<=k1+2;i++)
for(int n=k2;n<=k2+2;n++)
if(node[i][n].semaphore[m]==1)
{
sum++;
v1.push_back(i);
v1.push_back(n);
v2.push_back(v1);
v1.clear();
}
if(sum==1)//非回溯
{
int* p=new int[10];//p[1]到p[9]如果为1说明会被减去
for(int i=1;i<=9;i++)
p[i]=0;
for(int k=1;k<=m-1;k++)
if(node[v2[0][0]][v2[0][1]].semaphore[k]==1)
{
p[k]=1;//此时不对要减去的候选数进行操作,把它后延是因为后面还有更诱人的subtraction操作,让它先进行则更快
out_stream<<"行列区互相影响候选数删减法:"<<char(v2[0][0]-1+'A')<<v2[0][1]<<"应删"<<k<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(v2[0][0]-1+'A')<<v2[0][1]<<"应删"<<k<<"。"<<endl;
}
for(int k=m+1;k<=9 ;k++)
if(node[v2[0][0]][v2[0][1]].semaphore[k]==1)
{
p[k]=1;//此时不对要减去的候选数进行操作,把它后延是因为后面还有更诱人的subtraction操作,让它先进行则更快
out_stream<<"行列区互相影响候选数删减法:"<<char(v2[0][0]-1+'A')<<v2[0][1]<<"应删"<<k<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(v2[0][0]-1+'A')<<v2[0][1]<<"应删"<<k<<"。"<<endl;
}
for(int k=1;k<=9;k++)
node[v2[0][0]][v2[0][1]].semaphore[k]=0;
node[v2[0][0]][v2[0][1]].probable=0;
node[v2[0][0]][v2[0][1]].semaphore[10]=m;
out_stream<<"唯一数:"<<char(v2[0][0]-1+'A')<<v2[0][1]<<"应填"<<m<<"。"<<endl;
cout<<"唯一数:"<<char(v2[0][0]-1+'A')<<v2[0][1]<<"应填"<<m<<"。"<<endl;
subtraction(v2[0][0],v2[0][1],m);
for(int k=1;k<=9;k++)
if(p[k]==1)
{
row_technology(v2[0][0],k);
array_technology(v2[0][1],k);
room_technology(room(v2[0][0],v2[0][1]),k);
}
delete[] p;
}
else if(sum==2)//非回溯
{
if(v2[0][0]==v2[1][0])
{
int* p=new int[2];//存放它可能影响的两个宫
p[0]=0;p[1]=0;
for(int col=1;col<=k2-1 ;col++)
if(node[v2[0][0]][col].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(v2[0][0]-1+'A')<<col<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(v2[0][0]-1+'A')<<col<<"应删"<<m<<"。"<<endl;
node[v2[0][0]][col].semaphore[m]=0;//非回溯,技巧是(区块影响行列)候选数删减法
node[v2[0][0]][col].probable--;
if(node[v2[0][0]][col].probable==1)
call_subtraction(v2[0][0],col,1);
array_technology(col,m);//这里的调用可以迅速缩短得到结果时间,不管是正确还是错误
if(p[0]==0) p[0]=room(v2[0][0],col);
else if( p[0]!=room(v2[0][0],col)) p[1]=room(v2[0][0],col);
}
for(int col=k2+3; col<=9;col++)
if(node[v2[0][0]][col].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(v2[0][0]-1+'A')<<col<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(v2[0][0]-1+'A')<<col<<"应删"<<m<<"。"<<endl;
node[v2[0][0]][col].semaphore[m]=0;//非回溯,技巧是(区块影响行列)候选数删减法
node[v2[0][0]][col].probable--;
if(node[v2[0][0]][col].probable==1)
call_subtraction(v2[0][0],col,1);
array_technology(col,m);//这里的调用可以迅速缩短得到结果时间,不管是正确还是错误
if(p[0]==0) p[0]=room(v2[0][0],col);
else if( p[0]!=room(v2[0][0],col)) p[1]=room(v2[0][0],col);
}
if(p[0]!=0) room_technology(p[0],m);//p[0]!=0说明room p[0]中的候选数v[i]被减掉至少一个,如果剪掉两个就应该把这个语句放在for循环外面
if(p[1]!=0) room_technology(p[1],m);
delete[] p;
}
else if(v2[0][1]==v2[1][1])
{
int* p=new int[2];//存放它可能影响的两个宫
p[0]=0;p[1]=0;
for(int row=1;row<=k1-1;row++)
if(node[row][v2[0][1]].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(row-1+'A')<<v2[0][1]<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(row-1+'A')<<v2[0][1]<<"应删"<<m<<"。"<<endl;
node[row][v2[0][1]].semaphore[m]=0;//非回溯,技巧是(区块影响行列)候选数删减法
node[row][v2[0][1]].probable--;
if(node[row][v2[0][1]].probable==1)
call_subtraction(row,v2[0][1],1);
row_technology(row,m);//这里的调用可以迅速缩短得到结果时间,不管是正确还是错误
if(p[0]==0) p[0]=room(row,v2[0][1]);
else if( p[0]!=room(row,v2[0][1])) p[1]=room(row,v2[0][1]);
}
for(int row=k1+3; row<=9;row++)
if(node[row][v2[0][1]].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(row-1+'A')<<v2[0][1]<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(row-1+'A')<<v2[0][1]<<"应删"<<m<<"。"<<endl;
node[row][v2[0][1]].semaphore[m]=0;//非回溯,技巧是(区块影响行列)候选数删减法
node[row][v2[0][1]].probable--;
if(node[row][v2[0][1]].probable==1)
call_subtraction(row,v2[0][1],1);
row_technology(row,m);//这里的调用可以迅速缩短得到结果时间,不管是正确还是错误
if(p[0]==0) p[0]=room(row,v2[0][1]);
else if( p[0]!=room(row,v2[0][1])) p[1]=room(row,v2[0][1]);
}
if(p[0]!=0) room_technology(p[0],m);//p[0]!=0说明room p[0]中的候选数v[i]被减掉至少一个,如果剪掉两个就应该把这个语句放在for循环外面
if(p[1]!=0) room_technology(p[1],m);
delete[] p;
}
}
else if(sum==3)//非回溯
{
if(v2[0][0]==v2[1][0] && v2[0][0]==v2[2][0] )
{
int* p=new int[2];//存放它可能影响的两个宫
p[0]=0;p[1]=0;
for(int col=1;col<=k2-1 ;col++)
if(node[v2[0][0]][col].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(v2[0][0]-1+'A')<<col<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(v2[0][0]-1+'A')<<col<<"应删"<<m<<"。"<<endl;
node[v2[0][0]][col].semaphore[m]=0;//非回溯,技巧是(区块影响行列)候选数删减法
node[v2[0][0]][col].probable--;
if(node[v2[0][0]][col].probable==1)
call_subtraction(v2[0][0],col,1);
array_technology(col,m);//这里的调用可以迅速缩短得到结果时间,不管是正确还是错误
if(p[0]==0) p[0]=room(v2[0][0],col);
else if( p[0]!=room(v2[0][0],col)) p[1]=room(v2[0][0],col);
}
for(int col=k2+3; col<=9;col++)
if(node[v2[0][0]][col].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(v2[0][0]-1+'A')<<col<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(v2[0][0]-1+'A')<<col<<"应删"<<m<<"。"<<endl;
node[v2[0][0]][col].semaphore[m]=0;//非回溯,技巧是(区块影响行列)候选数删减法
node[v2[0][0]][col].probable--;
if(node[v2[0][0]][col].probable==1)
call_subtraction(v2[0][0],col,1);
array_technology(col,m);//这里的调用可以迅速缩短得到结果时间,不管是正确还是错误
if(p[0]==0) p[0]=room(v2[0][0],col);
else if( p[0]!=room(v2[0][0],col)) p[1]=room(v2[0][0],col);
}
if(p[0]!=0) room_technology(p[0],m);//p[0]!=0说明room p[0]中的候选数v[i]被减掉至少一个,如果剪掉两个就应该把这个语句放在for循环外面
if(p[1]!=0) room_technology(p[1],m);
delete[] p;
}
else if(v2[0][1]==v2[1][1] && v2[0][1]==v2[2][1])
{
int* p=new int[2];//存放它可能影响的两个宫
p[0]=0;p[1]=0;
for(int row=1;row<=k1-1;row++)
if(node[row][v2[0][1]].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(row-1+'A')<<v2[0][1]<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(row-1+'A')<<v2[0][1]<<"应删"<<m<<"。"<<endl;
node[row][v2[0][1]].semaphore[m]=0;//非回溯,技巧是(区块影响行列)候选数删减法
node[row][v2[0][1]].probable--;
if(node[row][v2[0][1]].probable==1)
call_subtraction(row,v2[0][1],1);
row_technology(row,m);//这里的调用可以迅速缩短得到结果时间,不管是正确还是错误
if(p[0]==0) p[0]=room(row,v2[0][1]);
else if( p[0]!=room(row,v2[0][1])) p[1]=room(row,v2[0][1]);
}
for(int row=k1+3; row<=9;row++)
if(node[row][v2[0][1]].semaphore[m]==1)
{
out_stream<<"行列区互相影响候选数删减法:"<<char(row-1+'A')<<v2[0][1]<<"应删"<<m<<"。"<<endl;
cout<<"行列区互相影响候选数删减法:"<<char(row-1+'A')<<v2[0][1]<<"应删"<<m<<"。"<<endl;
node[row][v2[0][1]].semaphore[m]=0;//非回溯,技巧是(区块影响行列)候选数删减法
node[row][v2[0][1]].probable--;
if(node[row][v2[0][1]].probable==1)
call_subtraction(row,v2[0][1],1);
row_technology(row,m);//这里的调用可以迅速缩短得到结果时间,不管是正确还是错误
if(p[0]==0) p[0]=room(row,v2[0][1]);
else if( p[0]!=room(row,v2[0][1])) p[1]=room(row,v2[0][1]);
}
if(p[0]!=0) room_technology(p[0],m);//p[0]!=0说明room p[0]中的候选数v[i]被减掉至少一个,如果剪掉两个就应该把这个语句放在for循环外面
if(p[1]!=0) room_technology(p[1],m);
delete[] p;
}
}
v2.clear();
}
void row_technology(int row )//k只能填在行的某一空上 或k只能填在这一行的某一宫中 i=1用技巧1,i=2用技巧2,i=3用技巧12
{
vector<int> v;
int col;
int *p=new int[10];
for(col=1;col<=9;col++)
p[col]=0;
for( col=1;col<=9;col++)
if(node[row][col].semaphore[10]!=0)
p[node[row][col].semaphore[10]]=1;
for(col=1;col<=9;col++)
if(p[col]==0)
v.push_back(col);
delete[] p;
if(v.size()==0) goto loop;
for(int i=v.size()-1;i>=0;i--)
row_technology(row,v[i]);
v.clear();
loop: ;
}
void technology_row()
{
for(int row=1;row<=9;row++)
row_technology(row);
}
void array_technology(int col)//k只能填在行的某一空上 或k只能填在这一列的某一宫上
{
vector<int> v;
int row;
int *p=new int[10];
for(row=1;row<=9;row++)
p[row]=0;
for( row=1;row<=9;row++)
if(node[row][col].semaphore[10]!=0)
p[node[row][col].semaphore[10]]=1;
for(row=1;row<=9;row++)
if(p[row]==0)
v.push_back(row);
delete[] p;
if(v.size()==0) goto loop;
for(int i=v.size()-1;i>=0;i--)
array_technology(col,v[i]);
v.clear();
loop: ;
}
void technology_array()
{
for(int col=1;col<=9;col++)
array_technology(col);
}
void room_technology(int i)//k只能填在某空上 或 k只能填在宫的某一行(列)上 , i表示room号,j=4表示遍历所有技巧,j=1表示此宫只有一个位置可填某候选数,j=2表示某候选数只能填在宫的某行,j=3表示某候选数只能填在某宫的某列
{
int k1=room(i)[0],k2=room(i)[1];
vector<int> v;
int m;
int *p=new int[10];
for(m=1;m<=9;m++)
p[m]=0;
for( m=k1;m<=k1+2;m++)
for(int n=k2;n<=k2+2;n++)
if(node[m][n].semaphore[10]!=0)
p[node[m][n].semaphore[10]]=1;
for(m=1;m<=9;m++)
if(p[m]==0)
v.push_back(m);
delete[] p;
if(v.size()==0) goto loop;
for( m=v.size()-1;m>=0;m--)
room_technology(i,v[m]);
v.clear();
loop: ;
}
void technology_room()
{
for(int i=1;i<=9;i++)
room_technology(i);
}
void easy_travel()
{
technology_row();
technology_array();
technology_room();
}
int count_candidate_number()
{
int sum=0;
for(int row=1;row<=9;row++)
for(int col=1;col<=9;col++)
if(node[row][col].probable==0) continue;
else
{
for(int k=1;k<=9;k++)
if(node[row][col].semaphore[k]==1) sum++;
}
return (sum);
}
bool easy_solve()
{
int i;
do{
i=count_candidate_number();
easy_travel();
}while(i!=count_candidate_number());
if(i==0) return(true);
else return (false);
}
int rectangle_2num(int row1,int row2,int col1,int col2)
{
return((probable_num(row1,col1)[0]==2)+(probable_num(row1,col2)[0]==2)+(probable_num(row2,col1)[0]==2)+(probable_num(row2,col2)[0]==2));
}
int probable_num(int row_or_col,int k,int t)//t=1表示第一个参数是行 t=0表示第一个参数是列,这里多加了个参数t是为了函数重载
{
int sum;
if(t==1)
{
sum=0;
for(int i=1;i<=9;i++)
sum+=node[row_or_col][i].semaphore[k];
return(sum);
}
else if(t==0)
{
sum=0;
for(int i=1;i<=9;i++)
sum+=node[i][row_or_col].semaphore[k];
return(sum);
}
}
/*void technology_rectangle()
{
vector<int> v1;
vector<vector<int>> v2;
for(int row=1;row<=9;row++)
for(int col=1;col<=9;col++)
if(probable_num(row,col)[0]==2)
{
int k1=probable_num(row,col)[1],k2=probable_num(row,col)[2];
for(int i=1;i<=9;i++)
for(int j=1;j<=9;j++)
if(node[i][j].semaphore[k1]==1 && node[i][j].semaphore[k2]==1)
{
v1.push_back(i);v1.push_back(j);v2.push_back(v1);v1.clear();
}
if(v2.size()<4) break;
for(int i=0;i<=v2.size()-1;)
{
int k=0;
int sentry=v2[i][0];
for(int j=i;j<=v2.size()-1;j++)
if(v2[j][0]==sentry) k++;
else break;
for(int m=i;m<=i+k-2;m++)
for(int n=m+1;n<=i+k-1;n++)
{
for(int p=i+k;p<=v2.size()-1;p++)
{
if(v2[m][1]==v2[p][1])
for(int q=p+1;q<=v2.size()-1;q++)
if(v2[n][1]==v2[q][1] && v2[q][0]==v2[p][0])
{
switch(rectangle_2num(v2[m][0],v2[p][0],v2[m][1],v2[n][1]))
{
case 1: if(probable_num(v2[m][0],v2[m][1])[0]==2 )
{
if(probable_num(v2[q][0],k1,1)==2 && probable_num(v2[q][1],k1,0)==2)
{
node[v2[q][0]][v2[q][1]].semaphore[k2]=0;//非回溯
node[v2[q][0]][v2[q][1]].probable--;
if(node[v2[q][0]][v2[q][1]].probable==1)
call_subtraction(v2[q][0],v2[q][1],1);
}
else if(probable_num(v2[q][0],k2,1)==2 && probable_num(v2[q][1],k2,0)==2)
{
node[v2[q][0]][v2[q][1]].semaphore[k1]=0;//非回溯
node[v2[q][0]][v2[q][1]].probable--;
if(node[v2[q][0]][v2[q][1]].probable==1)
call_subtraction(v2[q][0],v2[q][1],1);
}
else if( probable_num(v2[n][0],v2[n][1])[0]==3 &&probable_num(v2[p][0],v2[p][1])[0]==3 && probable_num(v2[q][0],v2[q][1])[0]==3)
{
int k=probable_num(v2[n][0],v2[n][1])[3];
if(probable_num(v2[p][0],v2[p][1])[3]==k && probable_num(v2[q][0],v2[q][1])[3]==k)
if(room(v2[p][0],v2[p][1])==room(v2[q][0],v2[q][1]) && room(v2[n][0],v2[n][1],v2[q][0],v2[q][1])==2 )
{
for(int i=room(room(v2[q][0],v2[q][1]))[0];i<=room(room(v2[q][0],v2[q][1]))[0]+2 && i!=v2[p][0];i++)
if(node[i][v2[q][1]].semaphore[k]==1)
{
node[i][v2[q][1]].semaphore[k]=0;//非回溯
node[i][v2[q][1]].probable--;
if( node[i][v2[q][1]].probable==1)
call_subtraction(i,v2[q][1],1);
}
}
else if(room(v2[n][0],v2[n][1])==room(v2[q][0],v2[q][1]) && room(v2[p][0],v2[p][1],v2[q][0],v2[q][1])==1)
{
for(int i=room(room(v2[q][0],v2[q][1]))[1];i<=room(room(v2[q][0],v2[q][1]))[1]+2 && i!=v2[q][1];i++)
if(node[v2[q][0]][i].semaphore[k]==1)
{
node[v2[q][0]][i].semaphore[k]=0;//非回溯
node[v2[q][0]][i].probable--;
if( node[v2[q][0]][i].probable==1)
call_subtraction(v2[q][0],i,1);
}
}
}
}
else if(probable_num(v2[n][0],v2[n][1])[0]==2)
{
if(probable_num(v2[p][0],k1,1)==2 && probable_num(v2[p][1],k1,0)==2)
{
node[v2[p][0]][v2[p][1]].semaphore[k2]=0;//非回溯
node[v2[p][0]][v2[p][1]].probable--;
if(node[v2[q][0]][v2[q][1]].probable==1)
call_subtraction(v2[p][0],v2[p][1],1);
}
else if(probable_num(v2[p][0],k2,1)==2 && probable_num(v2[p][1],k2,0)==2)
{
node[v2[p][0]][v2[p][1]].semaphore[k1]=0;//非回溯
node[v2[p][0]][v2[p][1]].probable--;
if(node[v2[p][0]][v2[p][1]].probable==1)
call_subtraction(v2[p][0],v2[p][1],1);
}
else if(probable_num(v2[m][0],v2[m][1])[0]==3 &&probable_num(v2[p][0],v2[p][1])[0]==3 && probable_num(v2[q][0],v2[q][1])[0]==3)
{
int k=probable_num(v2[m][0],v2[m][1])[3];
if(probable_num(v2[p][0],v2[p][1])[3]==k && probable_num(v2[q][0],v2[q][1])[3]==k)
if(room(v2[p][0],v2[p][1])==room(v2[q][0],v2[q][1]) && room(v2[m][0],v2[m][1],v2[p][0],v2[p][1])==2 )
{
for(int i=room(room(v2[p][0],v2[p][1]))[0];i<=room(room(v2[p][0],v2[p][1]))[0]+2 && i!=v2[p][0];i++)
if(node[i][v2[m][1]].semaphore[k]==1)
{
node[i][v2[m][1]].semaphore[k]=0;//非回溯
node[i][v2[m][1]].probable--;
if( node[i][v2[m][1]].probable==1)
call_subtraction(i,v2[m][1],1);
}
}
else if(room(v2[m][0],v2[m][1])==room(v2[p][0],v2[p][1]) && room(v2[p][0],v2[p][1],v2[q][0],v2[q][1])==1)
{
for(int i=room(room(v2[p][0],v2[p][1]))[1];i<=room(room(v2[p][0],v2[p][1]))[1]+2 && i!=v2[p][1];i++)
if(node[v2[q][0]][i].semaphore[k]==1)
{
node[v2[q][0]][i].semaphore[k]=0;//非回溯
node[v2[q][0]][i].probable--;
if( node[v2[q][0]][i].probable==1)
call_subtraction(v2[q][0],i,1);
}
}
}
}
else if(probable_num(v2[p][0],v2[p][1])[0]==2)
{
if(probable_num(v2[n][0],k1,1)==2 && probable_num(v2[n][1],k1,0)==2)
{
node[v2[n][0]][v2[n][1]].semaphore[k2]=0;//非回溯
node[v2[n][0]][v2[n][1]].probable--;
if(node[v2[n][0]][v2[n][1]].probable==1)
call_subtraction(v2[n][0],v2[n][1],1);
}
else if(probable_num(v2[n][0],k2,1)==2 && probable_num(v2[n][1],k2,0)==2)
{
node[v2[n][0]][v2[n][1]].semaphore[k1]=0;//非回溯
node[v2[n][0]][v2[n][1]].probable--;
if(node[v2[n][0]][v2[n][1]].probable==1)
call_subtraction(v2[n][0],v2[n][1],1);
}
else if(probable_num(v2[m][0],v2[m][1])[0]==3 && probable_num(v2[n][0],v2[n][1])[0]==3 && probable_num(v2[q][0],v2[q][1])[0]==3)
{
int k=probable_num(v2[n][0],v2[n][1])[3];
if(probable_num(v2[m][0],v2[m][1])[3]==k && probable_num(v2[q][0],v2[q][1])[3]==k)
if(room(v2[m][0],v2[m][1])==room(v2[n][0],v2[n][1]) && room(v2[n][0],v2[n][1],v2[q][0],v2[q][1])==2 )
{
for(int i=room(room(v2[m][0],v2[m][1]))[0];i<=room(room(v2[m][0],v2[m][1]))[0]+2 && i!=v2[n][0];i++)
if(node[i][v2[q][1]].semaphore[k]==1)
{
node[i][v2[q][1]].semaphore[k]=0;//非回溯
node[i][v2[q][1]].probable--;
if( node[i][v2[q][1]].probable==1)
call_subtraction(i,v2[q][1],1);
}
}
else if(room(v2[n][0],v2[n][1])==room(v2[q][0],v2[q][1]) && room(v2[m][0],v2[m][1],v2[n][0],v2[n][1])==1)
{
for(int i=room(room(v2[q][0],v2[q][1]))[1];i<=room(room(v2[q][0],v2[q][1]))[1]+2 && i!=v2[n][1];i++)
if(node[v2[m][0]][i].semaphore[k]==1 )
{
node[v2[m][0]][i].semaphore[k]=0;//非回溯
node[v2[m][0]][i].probable--;
if( node[v2[m][0]][i].probable==1)
call_subtraction(v2[m][0],i,1);
}
}
}
}
else if(probable_num(v2[q][0],v2[q][1])[0]==2)
{
if(probable_num(v2[m][0],k1,1)==2 && probable_num(v2[m][1],k1,0)==2)
{
node[v2[m][0]][v2[m][1]].semaphore[k2]=0;//非回溯//难度系数//中间过程提示
node[v2[m][0]][v2[m][1]].probable--;
if(node[v2[q][0]][v2[q][1]].probable==1)
call_subtraction(v2[m][0],v2[m][1],1);
}
else if(probable_num(v2[m][0],k2,1)==2 && probable_num(v2[m][1],k2,0)==2)
{
node[v2[m][0]][v2[m][1]].semaphore[k1]=0;//非回溯
node[v2[m][0]][v2[m][1]].probable--;
if(node[v2[m][0]][v2[m][1]].probable==1)
call_subtraction(v2[m][0],v2[m][1],1);
}
else if(probable_num(v2[m][0],v2[m][1])[0]==3 && probable_num(v2[n][0],v2[n][1])[0]==3 &&probable_num(v2[p][0],v2[p][1])[0]==3 )
{
int k=probable_num(v2[n][0],v2[n][1])[3];
if(probable_num(v2[p][0],v2[p][1])[3]==k && probable_num(v2[m][0],v2[m][1])[3]==k)
if(room(v2[m][0],v2[m][1])==room(v2[n][0],v2[n][1]) && room(v2[p][0],v2[p][1],v2[m][0],v2[m][1])==2 )
{
for(int i=room(room(v2[m][0],v2[m][1]))[0];i<=room(room(v2[m][0],v2[m][1]))[0]+2 && i!=v2[m][0];i++)
if(node[i][v2[p][1]].semaphore[k]==1)
{
node[i][v2[p][1]].semaphore[k]=0;//非回溯
node[i][v2[p][1]].probable--;
if( node[i][v2[p][1]].probable==1)
call_subtraction(i,v2[p][1],1);
}
}
else if(room(v2[m][0],v2[m][1])==room(v2[p][0],v2[p][1]) && room(v2[m][0],v2[m][1],v2[n][0],v2[n][1])==1)
{
for(int i=room(room(v2[m][0],v2[m][1]))[1];i<=room(room(v2[m][0],v2[m][1]))[1]+2 && i!=v2[m][1];i++)
if(node[v2[q][0]][i].semaphore[k]==1)
{
node[v2[n][0]][i].semaphore[k]=0;//非回溯
node[v2[n][0]][i].probable--;
if( node[v2[n][0]][i].probable==1)
call_subtraction(v2[n][0],i,1);
}
}
}
}
break;
case 2: if(probable_num(v2[m][0],v2[m][1])[0]==2 && probable_num(v2[q][0],v2[q][1])[0]==2 )
{
if(probable_num(v2[m][0],k1,1)==2 && probable_num(v2[m][1],k1,0)==2 && probable_num(v2[q][0],k1,1)==2 && probable_num(v2[q][1],k1,0)==2)
{
node[v2[n][0]][v2[n][1]].semaphore[k1]=0;//唯一解 矩形规避 级别4
node[v2[n][0]][v2[n][1]].probable--;
node[v2[p][0]][v2[p][1]].semaphore[k1]=0;//唯一解 矩形规避 级别4
node[v2[p][0]][v2[p][1]].probable--;
}
else if(probable_num(v2[m][0],k2,1)==2 && probable_num(v2[m][1],k2,0)==2 && probable_num(v2[q][0],k2,1)==2 && probable_num(v2[q][1],k2,0)==2)
{
node[v2[n][0]][v2[n][1]].semaphore[k2]=0;//唯一解 矩形规避 级别4
node[v2[n][0]][v2[n][1]].probable--;
node[v2[p][0]][v2[p][1]].semaphore[k2]=0;//唯一解 矩形规避 级别4
node[v2[p][0]][v2[p][1]].probable--;
}
}
else if(probable_num(v2[n][0],v2[n][1])[0]==2 && probable_num(v2[p][0],v2[p][1])[0]==2 )
{
if(probable_num(v2[n][0],k1,1)==2 && probable_num(v2[n][1],k1,0)==2 && probable_num(v2[p][0],k1,1)==2 && probable_num(v2[p][1],k1,0)==2)
{
node[v2[m][0]][v2[m][1]].semaphore[k1]=0;//唯一解 矩形规避 级别4
node[v2[m][0]][v2[m][1]].probable--;
node[v2[q][0]][v2[q][1]].semaphore[k1]=0;//唯一解 矩形规避 级别4
node[v2[q][0]][v2[q][1]].probable--;
}
else if(probable_num(v2[n][0],k2,1)==2 && probable_num(v2[n][1],k2,0)==2 && probable_num(v2[p][0],k2,1)==2 && probable_num(v2[p][1],k2,0)==2)
{
node[v2[m][0]][v2[m][1]].semaphore[k2]=0;//唯一解 矩形规避 级别4
node[v2[m][0]][v2[m][1]].probable--;
node[v2[q][0]][v2[q][1]].semaphore[k2]=0;//唯一解 矩形规避 级别4
node[v2[q][0]][v2[q][1]].probable--;
}
}
else if(probable_num(v2[n][0],v2[n][1])[0]==2 && probable_num(v2[m][0],v2[m][1])[0]==2 )
{
if(
}
else if(probable_num(v2[p][0],v2[p][1])[0]==2 && probable_num(v2[q][0],v2[q][1])[0]==2 )
{
}
else if(probable_num(v2[n][0],v2[n][1])[0]==2 && probable_num(v2[q][0],v2[q][1])[0]==2 )
{
}
else if(probable_num(v2[m][0],v2[m][1])[0]==2 && probable_num(v2[p][0],v2[p][1])[0]==2 )
{
}
break;
case 3:if(probable_num(v2[m][0],v2[m][1])[0]==3)
{
node[v2[m][0]][v2[m][1]].semaphore[k1]=0;//非回溯//难度系数定义//给出做题中间过程也可说提示
node[v2[m][0]][v2[m][1]].semaphore[k2]=0;//非回溯
node[v2[m][0]][v2[m][1]].probable-=2;
if(node[v2[m][0]][v2[m][1]].probable==1)
call_subtraction(v2[m][0],v2[m][1],1);
}
if(probable_num(v2[n][0],v2[n][1])[0]==3)
{
node[v2[n][0]][v2[n][1]].semaphore[k1]=0;//非回溯
node[v2[n][0]][v2[n][1]].semaphore[k2]=0;//非回溯
node[v2[n][0]][v2[n][1]].probable-=2;
if(node[v2[n][0]][v2[n][1]].probable==1)
call_subtraction(v2[n][0],v2[n][1],1);
}
if(probable_num(v2[p][0],v2[p][1])[0]==3)
{
node[v2[p][0]][v2[p][1]].semaphore[k1]=0;//非回溯
node[v2[p][0]][v2[p][1]].semaphore[k2]=0;//非回溯
node[v2[p][0]][v2[p][1]].probable-=2;
if(node[v2[p][0]][v2[p][1]].probable==1)
call_subtraction(v2[p][0],v2[p][1],1);
}
if(probable_num(v2[q][0],v2[q][1])[0]==3)
{
node[v2[q][0]][v2[q][1]].semaphore[k1]=0;//非回溯
node[v2[q][0]][v2[q][1]].semaphore[k2]=0;//非回溯
node[v2[q][0]][v2[q][1]].probable-=2;
if(node[v2[q][0]][v2[q][1]].probable==1)
call_subtraction(v2[q][0],v2[q][1],1);
}
}
break;
}
}
}
i+=k;
}
v2.clear();
}
}*/
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 test()
{
int sum=0,i,j;
for(int i=1;i<=9;i++)
{
sum=0;
for(int j=1;j<=9;j++)
sum+=node[i][j].semaphore[10];
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
}
for( j=1;j<=9;j++)
{
sum=0;
for(i=1;i<=9;i++)
sum+=node[i][j].semaphore[10];
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
}
sum=0;
for(i=1;i<=3;i++)
for(j=1;j<=3;j++)
sum+=node[i][j].semaphore[10];
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
sum=0;
for(i=1;i<=3;i++)
for(j=4;j<=6;j++)
sum+=node[i][j].semaphore[10];
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
sum=0;
for(i=1;i<=3;i++)
for(j=7;j<=9;j++)
sum+=node[i][j].semaphore[10];
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
sum=0;
for(i=4;i<=6;i++)
for(j=1;j<=3;j++)
sum+=node[i][j].semaphore[10];
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
sum=0;
for(i=4;i<=6;i++)
for(j=4;j<=6;j++)
sum+=node[i][j].semaphore[10];
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
sum=0;
for(i=4;i<=6;i++)
for(j=7;j<=9;j++)
sum+=node[i][j].semaphore[10];
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
sum=0;
for(i=7;i<=9;i++)
for(j=1;j<=3;j++)
sum+=node[i][j].semaphore[10];
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
sum=0;
for(i=7;i<=9;i++)
for(j=4;j<=6;j++)
sum+=node[i][j].semaphore[10];
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
sum=0;
for(i=7;i<=9;i++)
for(j=7;j<=9;j++)
sum+=node[i][j].semaphore[10];
if(sum!=45) {cout<<"wrong"<<endl; return 0;}
return 1;
}
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(vector<vector<int>> v2) //数据输入后,检查数据有没有同一行(列,方块)输入同一个数字
{
int matrix[10][10]={0};
int i,j,array[10],index=0;
for(i=0;i<=v2.size()-1;i++)
matrix[v2[i][0]][v2[i][1]]=v2[i][2];
for(i=1;i<=9;i++)
if(!fun(matrix[i])) { cout<<"您的输入有误或题目错误,第"<<i<<"行输入了两个相等的数 要不就是设计数独的人太愚蠢"<<endl; return 0;}
for(j=1;j<=9;j++)
{
for(i=1;i<=9;i++)
array[i]=matrix[i][j];
if(!fun(array)) { cout<<"您的输入有误或题目错误,第"<<j<<"列输入了两个相等的数 要不就是设计数独的人太愚蠢"<<endl; return 0;}
}
for(i=1;i<=3;i++)
for(j=1;j<=3;j++)
array[++index]=matrix[i][j];
if(!fun(array)) { cout<<"您的输入有误或题目错误,九个块其中一块输入了两个相等的数 要不就是设计数独的人太愚蠢"<<endl; return 0;}
index=0;
for(i=1;i<=3;i++)
for(j=4;j<=6;j++)
array[++index]=matrix[i][j];
if(!fun(array)) { cout<<"您的输入有误或题目错误,九个块其中一块输入了两个相等的数 要不就是设计数独的人太愚蠢"<<endl; return 0;}
index=0;
for(i=1;i<=3;i++)
for(j=7;j<=9;j++)
array[++index]=matrix[i][j];
if(!fun(array)) { cout<<"您的输入有误或题目错误,九个块其中一块输入了两个相等的数 要不就是设计数独的人太愚蠢"<<endl; return 0;}
index=0;
for(i=4;i<=6;i++)
for(j=1;j<=3;j++)
array[++index]=matrix[i][j];
if(!fun(array)) { cout<<"您的输入有误或题目错误,九个块其中一块输入了两个相等的数 要不就是设计数独的人太愚蠢"<<endl; return 0;}
index=0;
for(i=4;i<=6;i++)
for(j=4;j<=6;j++)
array[++index]=matrix[i][j];
if(!fun(array)) { cout<<"您的输入有误或题目错误,九个块其中一块输入了两个相等的数 要不就是设计数独的人太愚蠢"<<endl; return 0;}
index=0;
for(i=4;i<=6;i++)
for(j=7;j<=9;j++)
array[++index]=matrix[i][j];
if(!fun(array)) { cout<<"您的输入有误或题目错误,九个块其中一块输入了两个相等的数 要不就是设计数独的人太愚蠢"<<endl; return 0;}
index=0;
for(i=7;i<=9;i++)
for(j=1;j<=3;j++)
array[++index]=matrix[i][j];
if(!fun(array)) { cout<<"您的输入有误或题目错误,九个块其中一块输入了两个相等的数 要不就是设计数独的人太愚蠢"<<endl; return 0;}
index=0;
for(i=7;i<=9;i++)
for(j=4;j<=6;j++)
array[++index]=matrix[i][j];
if(!fun(array)) { cout<<"您的输入有误或题目错误,九个块其中一块输入了两个相等的数 要不就是设计数独的人太愚蠢"<<endl; return 0;}
index=0;
for(i=7;i<=9;i++)
for(j=7;j<=9;j++)
array[++index]=matrix[i][j];
if(!fun(array)) { cout<<"您的输入有误或题目错误,九个块其中一块输入了两个相等的数 要不就是设计数独的人太愚蠢"<<endl; return 0;}
return 1;
}
int main()
{
int information_number=0;
long time;
char char_start[82];
int int_start[82];
ifstream cin_stream;
//for( int i=1;i<82;i++)
// cin>>char_start[i];
cin_stream.open("d:\\c++\\数独12\\question\\3.txt");
cin_stream>>char_start;
for(int i=1;i<82;i++)
int_start[i]=char_start[i-1]-'0';
for(int i=1;i<82;i++)
{
int row,col;
if(int_start[i]!=0)
{
row=(i-1)/9+1;
col=i-9*(row-1);
v1.push_back(row);
v1.push_back(col);
v1.push_back(int_start[i]);
v2.push_back(v1);
vstart.push_back(v1);
v1.clear();
}
}
information_number=v2.size();
cin_stream.close();
out_stream.open("d:\\c++\\数独12\\question\\question474.txt");
for(int i=0;i<information_number;i++)
if(v2[i][2]<1 || v2[i][2]>9)
{
cout<<"输入错误,要填入九宫格中的数字不在1--9内 或行号和列号不在9内,您没有按格式输入,请重新运行并输入 要不就是设计数独的人太愚蠢"<<endl;
system("pause");
return 0;
}
if(!test(v2))
{
system("pause");
return 0;
}
time=clock();
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];
}
out_stream<<"输出题目,请核对"<<endl;
print_all();//这里是输出题目,看看自己输入是否正确
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();
out_stream<<"根据题目第一轮subtraction后结果(还没用技巧)"<<endl;
print_all();//这里是不用技巧时得到的解题结果
if(finished==81)
{
out_stream<<endl;
if(test()) { time=clock()-time; out_stream<<"用时(不含输入数据时间)"<<time/1000<<"秒"<<time%1000<<"毫秒"<<endl; cout<<"right"<<endl;}
out_stream<<"题目很简单,第一轮subtraction就KO"<<endl;
print_all();
system("pause");
return 0;
}
if(easy_solve())
{
if(test())
{
time=clock()-time;
out_stream<<"用时(不含输入数据时间)"<<time/1000<<"秒"<<time%1000<<"毫秒"<<endl;
out_stream<<"简单技巧用到极致后KO"<<endl;
print_all();
cout<<"right"<<endl;
}
}
else
{
out_stream<<"简单技巧用到极致也解决不了,下面是中间结果"<<endl;
print_all();//这是简单技巧用到极致后的结果,这个结果是绝对正确的,只是还没解出来。
}
explore();
if(test())
{
time=clock()-time;
out_stream<<"用时(不含输入数据时间)"<<time/1000<<"秒"<<time%1000<<"毫秒"<<endl;
out_stream<<"最快回溯法KO"<<endl;
print_all();
cout<<"用时(不含输入数据时间)"<<time/1000<<"秒"<<time%1000<<"毫秒"<<endl;
cout<<"right"<<endl;
}
out_stream.close();
system("pause");
}
s(vstart_and_v3)_(e_tec)_(no_tec_rec)相关推荐
- MATLAB_4-形态学_腐蚀_膨胀_灰度图的腐蚀以及膨胀_开运算_闭运算_文章末尾有几个素材例子
素材链接: MATLAB_4-形态学_课程需要的素材 记住单词拼写: 腐蚀 erode 膨胀 dilate 开运算 open 闭运算 close 图像重建 imreconstruct reconstr ...
- 计算机会计课程试题及答案,计算机会计第2次作业_报表_附答案
计算机会计第2次作业_报表_附答案 (6页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 . . . . .<计算机会计>课程作业 ...
- java语言仅支持单重继承_java语言程序设计基础篇习题_复习题_第十一章
java语言程序设计基础篇习题_复习题_第十一章 11.1 下面说法是真是假?一个子类是父类的子集. 11.2 使用什么关键字来定义一个子类 11.3 什么是单一继承?什么是多重继承?java支持多重 ...
- 宏定义中的#、##操作符和... 、 _ _VA_ARGS_ _解析
# #符号作为一个预处理运算符,它可以把语言符号转化成字符串.例如,如果x是一个宏参量,那么#x可以把参数名转化成相应的字符串.该过程称为字符串化(stringizing). 例子 #incldu ...
- 计算机软件专业 课程,_计算机软件_专业的课程设置.pdf
_计算机软件_专业的课程设置.pdf 机械职业教育 2007.5 专业建设 - - 27 计算机软件 专业的课程设置 < > ◎ 方一新 王 竝 摘 要 职业教育必须坚持以就业为导向 加快 ...
- C++语言程序设计视频教程_清华大学_郑莉(基础篇+进阶篇)
C++语言程序设计视频教程_清华大学_郑莉(基础篇) 第一章:绪论 1.1 导学 1.2 计算机系统简介 1.3计算机语言和程序设计方法的发展 1.4 面向对象的基本概念 1.5 程序的开发过程 1. ...
- 统计_statistics_不同的人_大样本_分析_统计方法_useful ?
统计_statistics_不同的人_大样本_分析_ 转载于:https://www.cnblogs.com/books2read/p/11313825.html
- 作业调度算法--高响应比优先 操作系统_处理器管理_编程题
操作系统_处理器管理_编程题 作业调度算法–高响应比优先 输入N个作业,输入每个的作业名字,到达的时间,服务的时间,根据高响应比优先算法,计算出每个作业的完成的时间,周转的时间,带权周转的时间(其中保 ...
- 作业调度算法--短作业优先 操作系统_处理器管理_编程题
操作系统_处理器管理_编程题 作业调度算法–短作业优先 输入N个作业,输入每个的作业名字,到达的时间,服务的时间,根据短作业优先算法,计算出每个作业的完成的时间,周转的时间,带权周转的时间(其中保留2 ...
最新文章
- SQL Server 2012 安全新特性:包含数据库
- 动静结合学内核:linux idle进程和init进程浅析
- .net HtmlParser初步使用研究
- 用Python机器学习搞定验证码
- javascript 调用c#变量实例
- php解析目录函数怎么用,PHP中目录解析函数
- DEDE常见的错误(转)
- 论文笔记_S2D.38_2018-CVPR_DORN_用于单目深度估计的深度有序回归网络
- 百炼-2726:采药
- HeadFirstJava
- 外贸建站需要注意的事项
- Windows 关闭端口号
- html如何链接icon,iconfont在线链接使用
- html好看的后台页面布局,25 个精美的后台管理界面模板和布局
- python画3维图_python如何画三维图像?
- NGUI动态字体教程
- 基于RWEQ模型的土壤风蚀模数估算及其变化归因分析
- 计算机如果添加新用户名,怎么在电脑中创建新用户
- C++实现简单电话通讯录
- SQL中除法计算保留整数或几位小数(除法那些事儿!)
热门文章
- 地理信息系统的雷达回波图
- 智能IP先锋:从园区网络智能变革,到数字化转型新突破
- 【笔记整理】图解设计模式 | 第12章 Decorator模式(装饰边框与被装饰物的一致性)
- linux擦除硬盘数据命令_轻松擦除,删除和安全销毁硬盘数据
- 车辆总线数据采集知识分享
- 中国x86服务器全年销售额idc,2015年第二季度中国x86服务器市场IDC报告精华就在这了!...
- 精心整理!分享25个适合三维爱好者的模型网站与数百款场景模型
- android模拟器背景色,安卓开发者必备的5款App:终端模拟器、颜色萃取、移动IDE等...
- OLAP和OLTP以及HTAP的区别
- 乘性散斑噪声理论及其仿真实例分析-Matlab源代码