测试not_w_add(mate)_no_tec_rec1修改2

QQ及邮箱:1  4 2 3 1 7 3 7 8 3 @qq.com欢迎吹毛求疵。

//测试用时   用时213609秒47毫秒约59.3358h
//本代码进行了以下改动,min_probable_node全局变量取消   explore一旦得到正确结果马上返回   这两个改动耗时没有减少
//void explore()  改为  bool explore();  递归看起来逻辑更清晰,空间复杂度也有微微降低,耗时不变
//node结构体中数据结构也做了修改,删减了不必要的变量设置。
//这一测试代码检查功能全面,有题目检查,45法检查,小集团不同检查
//   op设为全局变量,可对怪题的出现频率有个感性的认识,但不准确.  同时把怪题和测试不通过的题目分开写入不同文件中。
//  如果59空题太简单,不explore就能手工做出来,改过代码后这样的题会打印出来。这种情况之前没有考虑。
#include<iostream>
#include<fstream>
#include<vector>
#include<time.h>
#include<cstdlib>
using namespace std;
#define BLANKS   59
#define FAIL     20
int table[9][9],table_for_solve[9][9],solves=0;
struct{
    int semaphore[11];//semaphore[10]表示存储值
 int probable;
 int probable_explore_recover;
 } node[10][10];
int finished=0,count=0,probablew[10][10],storagew[10][10];//probablew  storagew 是为了调试设置的,时空复杂度增加可忽略不计
unsigned op;                 //设为全局变量,调试过程在任何函数卡壳时可知道是第几个题目卡壳,从而知道这样的怪题的出现频率
ofstream out_stream1,out_stream2;
vector<int>  v1;
vector<vector<int>> v2,success;
vector<vector<vector<int>>>    v3;

 

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 print_all();
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);  //输出到文件1,2,   1文件放怪题   2文件放测试不通过题
void copy(int a[9][9],int b[9][9]);

 

int room(int row,int col);                                //返回node[row][col]所在的宫号
void fills_up();                                    //开始时要初始化node[10][10],使得每个节点的候选数semaphore[1--9]全为1,probable为9,填写值semaphore[10]为0;
vector<vector<int>> subtracion(int row,int col);//当node[row][col]只有一个候选数可填,且知道这个候选数,调用此函数(回溯版)
void add(int row,int col,int storage,vector<int> must_add);            //node[row][col]曾经填了storage并且把别的格的storage候选数减去,这些格子的行号和列号记录在must_add中,减什么就恢复什么
void addv2(vector<vector<int>> & v2);                                     //explore()在min_probable_node的某个k(候选数)上探测得到错误结果,这时所有的探索记录保存在全局变量v2中。
bool explore();                                       //当所有技巧或模式都用到极致时(当然也可以不用到极致,有时回溯法要来得更快,或者遍历模式耗时太长还不如回溯来得快,当然解题高手的兴奋点是最短时间发现已经知道的最难的推理模式,或发现新的不同难度系数的推理模式)要用回溯法(回溯法可嵌入技巧,一般以常用到遍历耗时短的技巧嵌入为佳),回溯法没有返回值,没有参数,形参其实就是全局变量v2,v1,返回值其实是全局变量finished
int test();                               //当题目解完时检测题目有没有解错,方法是每行每列每宫的和都要是45.其实技巧法和回溯法都能用数学证明,只要填满81个格就一定是正确的,但这个函数耗时不到1毫秒  就保存了下来。
bool  fun( int array[10]);              //数组array的九个数如有重复返回false
bool in_not_wrong_add(int row,int col,vector<int> not_wrong_add);  //node[row][col]在not_wrong_add中则返回true

 

 


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 print_all()

 cout<<"print storage"<<endl;
   for(int i=1;i<=9;i++)
     {
    for(int j=1;j<=9;j++)
     {
   cout<<table[i-1][j-1]<<" ";
     if(j%3==0) cout<<"   ";
     }   
    cout<<endl;
    if(i%3==0)  cout<<endl;
     }
   cout<<endl<<endl;
}
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)

   if(k==1)
   {
  for(int i=1;i<=9;i++)
     {
     if(i%3==1)  out_stream1<<endl;
  for(int j=1;j<=9;j++)
     {
      if(j%3==1) out_stream1<<"  ";
   out_stream1<<table[i-1][j-1];
     }   
    out_stream1<<endl;
     }
    out_stream1<<endl<<endl;
   }
   else if(k==2)
   {
      for(int i=1;i<=9;i++)
     {
     if(i%3==1)  out_stream2<<endl;
  for(int j=1;j<=9;j++)
     {
      if(j%3==1) out_stream2<<"  ";
   out_stream2<<table[i-1][j-1];
     }   
    out_stream2<<endl;
     }
    out_stream2<<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);
}
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[10]=0;
   node[i][j].probable=9;
   node[i][j].probable_explore_recover=0;
   probablew[i][j]=9;
   storagew[i][j]=0;
  }
}
vector<vector<int>> subtraction(int row,int col,int storage)
{
 finished++;
 if(finished==81)  return success;
 vector<vector<int>>   temp;
 vector<int>  not_wrong_add;
 for(int j=1;j<=9;j++) 
  if(node[row][j].semaphore[storage]==1 && node[row][j].probable!=0)
   {
    node[row][j].semaphore[storage]=0;    //把节点中不能填的点排除
    node[row][j].probable-=1;                                             //probable即可能填的数目减1
    probablew[row][j]--;
    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)
                {
               not_wrong_add.push_back(100);
             v2.push_back(not_wrong_add);
             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)
                {
               not_wrong_add.push_back(100);
             v2.push_back(not_wrong_add);
             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))
              {
                 not_wrong_add.push_back(100);
             v2.push_back(not_wrong_add);
               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;
           storagew[row][j]=k;
           probablew[row][j]=0;
           not_wrong_add.push_back(10);
                                   v2.push_back(not_wrong_add);
           v1.push_back(row);
              v1.push_back(j);
              v1.push_back(k);
              v1.push_back(10);
              v2.push_back(v1);
              v1.clear();
                 temp=subtraction(row,j,k);
              if(temp==success)    return success;
              if(temp[v2.size()-1][3]>30 && temp[v2.size()-1][3]!=400 )   
               goto  loop;
           if(temp[v2.size()-1][3]==400)
            not_wrong_add.pop_back();
                                }
    }
         }
  else  if(node[row][j].semaphore[storage]==0 && node[row][j].probable!=0)
  {  
   not_wrong_add.push_back(row);
   not_wrong_add.push_back(j);
  }
 for(int i=1;i<=9;i++) 
  if(node[i][col].semaphore[storage]==1 && node[i][col].probable!=0)
   {
    node[i][col].semaphore[storage]=0;    //把节点中不能填的点排除
    node[i][col].probable-=1;               //probable即可能填的数目减1
    probablew[i][col]--;
    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)
                {
                not_wrong_add.push_back(200);
             v2.push_back(not_wrong_add);
             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)
                {
                not_wrong_add.push_back(200);
             v2.push_back(not_wrong_add);
             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))
                   {
                   not_wrong_add.push_back(200);
             v2.push_back(not_wrong_add);
             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;
           storagew[i][col]=k;
           probablew[i][col]=0;
           not_wrong_add.push_back(20);
                                   v2.push_back(not_wrong_add);             
           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,k);
              if(temp==success)    return success;
              if(temp[v2.size()-1][3]>30 && temp[v2.size()-1][3]!=400 )   
               goto  loop;
           if(temp[v2.size()-1][3]==400)
            not_wrong_add.pop_back();
                                }
    }
         }
  else  if(node[i][col].semaphore[storage]==0 && node[i][col].probable!=0)   
  {  
   not_wrong_add.push_back(i);
   not_wrong_add.push_back(col);
  }
     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(i==row) break;//调试后发现 如果区块中碰到在行列中已经减掉k=storage值,但node[row][col].probable!=0  这是node[i][j]其实被减但会压入not_wrong_add中最后得不到修复
    if(j==col) continue;
    if(node[i][j].semaphore[storage]==1 && node[i][j].probable!=0)
                   {
                     node[i][j].semaphore[storage]=0;    //把节点中不能填的点排除
                      node[i][j].probable-=1;          //probable即可能填的数目减1
          probablew[i][j]--;
                     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)
               {
                not_wrong_add.push_back(300);
                v2.push_back(not_wrong_add);
                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)
               {
                not_wrong_add.push_back(300);
                v2.push_back(not_wrong_add);
                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))
                  {
                 not_wrong_add.push_back(300);
                      v2.push_back(not_wrong_add);
                   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;
             storagew[i][j]=k;
             probablew[i][j]=0;
                      not_wrong_add.push_back(30);
                                              v2.push_back(not_wrong_add);              
                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,k);
                         if(temp==success)    return success;
                         if(temp[v2.size()-1][3]>30 && temp[v2.size()-1][3]!=400 )   
                         goto  loop;
             if(temp[v2.size()-1][3]==400)
              not_wrong_add.pop_back();
                     }
                        }
                         }
        else  if(node[i][j].semaphore[storage]==0 && node[i][j].probable!=0)   
                      {  
                               not_wrong_add.push_back(i);
                              not_wrong_add.push_back(j);
                      }   
   }
     not_wrong_add.push_back(400);
 v2.push_back(not_wrong_add);     
 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;
}
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+=node[i][j].semaphore[10];  aray[j]=node[i][j].semaphore[10];}
   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+=node[i][j].semaphore[10];  aray[i]=node[i][j].semaphore[10];}
   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+=node[i][j].semaphore[10];  aray[sub++]=node[i][j].semaphore[10];}
        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);
}
bool in_not_wrong_add(int row,int col,vector<int> not_wrong_add) //node[row][col]在not_wrong_add中则返回true
{
  for(int i=1;  i<=(not_wrong_add.size()-1)/2;   i++)
   if(row==not_wrong_add[2*i-2] && col==not_wrong_add[2*i-1])
   return (true);
  return (false);
}
void add(int row1,int col1,int row2,int col2,int storage,int semaphore,vector<int> not_wrong_add)//semaphore的值为100,200,300,400  表示从四个方向上恢复
{
 finished--;
 switch(semaphore)
         {
      case 100:   for(int j=col2;j>=1;j--)
                            if(node[row1][j].semaphore[storage]==0 && node[row1][j].probable!=0 && !in_not_wrong_add(row1,j,not_wrong_add) )//这一行最后面那个函数是调试后打的补丁  用处是不该恢复的不恢复
            {
            node[row1][j].semaphore[storage]=1;
            node[row1][j].probable+=1;
         probablew[row1][j]++;
        }  break;
      case 200:   for(int i=row2;i>=1;i--)
                            if(node[i][col2].semaphore[storage]==0 && node[i][col2].probable!=0 && !in_not_wrong_add(i,col2,not_wrong_add) )
            {
            node[i][col2].semaphore[storage]=1;
            node[i][col2].probable+=1;
         probablew[i][col2]++;
        }
      for(int j=9;j>=1;j--)
                            if(node[row1][j].semaphore[storage]==0 && node[row1][j].probable!=0 && !in_not_wrong_add(row1,j,not_wrong_add) )
            {
            node[row1][j].semaphore[storage]=1;
            node[row1][j].probable+=1;
         probablew[row1][j]++;
        }  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 && !in_not_wrong_add(row2,j,not_wrong_add) )
        {
         node[row2][j].semaphore[storage]=1;
         node[row2][j].probable+=1;
         probablew[row2][j]++;
        }
       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 && !in_not_wrong_add(i,j,not_wrong_add) )
         {
             node[i][j].semaphore[storage]=1;
             node[i][j].probable+=1;
          probablew[i][j]++;
         }
          for(int i=9;i>=1;i--)
                                  if(node[i][col1].semaphore[storage]==0 && node[i][col1].probable!=0 && !in_not_wrong_add(i,col1,not_wrong_add) )
                {
                node[i][col1].semaphore[storage]=1;
                node[i][col1].probable+=1;
          probablew[i][col1]++;
            }
             for(int j=9;j>=1;j--)
                                 if(node[row1][j].semaphore[storage]==0 && node[row1][j].probable!=0 && !in_not_wrong_add(row1,j,not_wrong_add))
               {
            node[row1][j].semaphore[storage]=1;
            node[row1][j].probable+=1;
         probablew[row1][j]++;
            }
       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 && !in_not_wrong_add(i,j,not_wrong_add))
         {
             node[i][j].semaphore[storage]=1;
             node[i][j].probable+=1;
          probablew[i][j]++;
         }
          for(int i=9;i>=1;i--)
                                  if(node[i][col1].semaphore[storage]==0 && node[i][col1].probable!=0 && !in_not_wrong_add(i,col1,not_wrong_add))
                {
                node[i][col1].semaphore[storage]=1;
                node[i][col1].probable+=1;
          probablew[i][col1]++;
            }
             for(int j=9;j>=1;j--)
                                 if(node[row1][j].semaphore[storage]==0 && node[row1][j].probable!=0 && !in_not_wrong_add(row1,j,not_wrong_add))
               {
            node[row1][j].semaphore[storage]=1;
            node[row1][j].probable+=1;
         probablew[row1][j]++;
            }
       break;  
     }
 node[row1][col1].semaphore[storage]=1;
 node[row1][col1].probable+=1;   //node[row][col].storage的值最后变回0,下面恢复三个区域要用到这个值。
 node[row1][col1].semaphore[10]=0;
 probablew[row1][col1]++;
 storagew[row1][col1]=0;
 if(node[row1][col1].probable_explore_recover!=0)
    {
  probablew[row1][col1]=node[row1][col1].probable=node[row1][col1].probable_explore_recover;
  node[row1][col1].probable_explore_recover=0;  //调试发现的,后来加上
    }
}
void addv2(vector<vector<int>> & v2)
 {
  vector<vector<int>>  v2_transcript;
  v2_transcript.push_back(v2[v2.size()-1]);
  v2_transcript.push_back(v2[v2.size()-2]);
  v2.pop_back();
  v2.pop_back();
  for( int i=v2.size()-1;i>=0;i--)
  {
   if( v2[i][v2[i].size()-1]==400)
    {
     v2_transcript.push_back(v2[i]);
     v2.pop_back();
     continue;
     } 
   if(v2_transcript[v2_transcript.size()-2][3]==400 && v2.size()>1 )//  && v2_transcript[v2_transcript.size()-1][0]==v2[i][0] && v2_transcript[v2_transcript.size()-1][1]==v2[i][1] )
   {
    add(v2[i][0],v2[i][1],v2[i][0],v2[i][1],v2[i][2],400,v2_transcript[v2_transcript.size()-1]);
    v2_transcript.pop_back();
    v2_transcript.pop_back();
    v2.pop_back();
    v2.pop_back();
    i--;
    continue;
    }
     if(v2.size()>1 && (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[1]);
  v2_transcript.pop_back();
  v2_transcript.pop_back();
  v2_transcript.push_back(v2[i]);
  v2_transcript.push_back(v2[i-1]);
  v2.pop_back();
  v2.pop_back();
  i--;
  continue;
  } 
     if(v2.size()==1 && (v2_transcript[0][3]==10  || v2_transcript[0][3]==20 || v2_transcript[0][3]==30) )
     {
  add(v2[0][0],v2[0][1],v2_transcript[0][0],v2_transcript[0][1],v2[0][2],v2_transcript[0][3]*10,v2_transcript[1]);
  v2_transcript.pop_back();
  v2_transcript.pop_back();
  v2.pop_back();
  break;
  } 
     if( v2.size()==1 && v2_transcript[0][3]==400 )
     {
  add(v2[0][0],v2[0][1],v2[0][0],v2[0][1],v2[0][2],400,v2_transcript[1]);
  v2_transcript.pop_back();
  v2_transcript.pop_back();
  v2.pop_back();
  break;
  } 
     if(v2.size()>1 && (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[1]);
  v2_transcript.pop_back();
  v2_transcript.pop_back();
  v2_transcript.push_back(v2[i]);
  v2_transcript.push_back(v2[i-1]);
  v2.pop_back();
  v2.pop_back();
  i--;
  continue;
  } 
     if(v2.size()==1  && ((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[1]);
  v2_transcript.pop_back();
  v2_transcript.pop_back();
  v2.pop_back();
  break;
  } 
  }//for
 }
bool 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;
      }
            }
         }
          count++;
    for(int k=1;k<=9;k++)
                   {
           if(node[row][col].semaphore[k]==1)
          { 
                        for(int r=1;r<=9;r++)
       if(node[row][r].semaphore[10]==k )
        goto loop;
      for(int r=1;r<=9;r++)
       if(node[r][col].semaphore[10]==k )
        goto loop;
         for( int i=(room(row,col)-1)/3*3+1;i<=(room(row,col)-1)/3*3+3;i++)
         for(int j=(room(row,col)-1)%3*3+1;j<=(room(row,col)-1)%3*3+3;j++)
           if(node[i][j].semaphore[10]==k)
           goto loop;
      //for(int r=1;r<=9;r++)
           //   node[row][col].semaphore_explore_recover[r]=node[row][col].semaphore[r];
        node[row][col].probable_explore_recover=node[row][col].probable;
        //for(int r=1;r<=9;r++)
                         //        node[row][col].semaphore[r]=0;
                       node[row][col].probable=0;
                       node[row][col].semaphore[10]=k;
        probablew[row][col]=0;
        storagew[row][col]=k;
        v1.push_back(row);
        v1.push_back(col);
                    v1.push_back(k);
        v1.push_back(0);
        v2.push_back(v1);
                    v1.clear();
        if(subtraction(row,col,k)==success)
              return(true);
            else if(v2[v2.size()-1][3]>30 && v2[v2.size()-1][3]!=400) 
             {
        addv2(v2);
        v2.clear();
       }
            else  
             {
            v3.push_back(v2);
           v2.clear();
           explore();
        if(finished==81)  return(true);
        else  
          {
                          addv2(v3[v3.size()-1]);
                          v3.pop_back();
          }
             }
      }
   loop: ;  
    }
    return(false);

 

 int main()
{
 int row,col,number,information_number=0;
 long time1; 
 time1=clock(); 
 out_stream1.open("d:\\c++\\数独12\\question\\question470.txt");
 out_stream2.open("d:\\c++\\数独12\\question\\question471.txt");
 srand((unsigned int)time(NULL));
 for( op=1;op<=1000000;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];
  probablew[v2[i][0]][v2[i][1]]=0;
  storagew[v2[i][0]][v2[i][1]]=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],v2[i][2]);
   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())  
 {
  //out_stream2<<"1000000题目中第"<<op<<"个题目出现55空格超简单数独题目"<<endl;
  //print_all(2);
  v2.clear();  v3.clear();   finished=0;
  continue;       //这条语句很关键  保证不进入explore
 }
 explore();
 if(test()) ;
 else  { out_stream1<<"1000000题目中第"<<op<<"个题目测试不通过"<<endl; print_all(1);}
 v2.clear();  v3.clear();   finished=0;
 }//op
 time1=clock()-time1;
 out_stream1<<"用时"<<time1/1000<<"秒"<<time1%1000<<"毫秒"<<endl;
 out_stream1.close();
 out_stream2.close();
 }

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值