測試not_w_add(mate)_(e_t)_no_tec_rec

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

//fenlan那題用了380s  不可思議     實際耗時約59.01h   中途可能待機所以不一定準確。
#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;
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]);

 

int room(int row,int col);                                //返回node[row][col]所在的宮號的行起始號和列起始號,它們分別存儲在全局數組中subscript[2]
void fills_up();                                    //開始
int* room(int k);                                     //返回宮K時要初始化node[10][10],使得每個節點的候選數semaphore[1--9]全爲1,probable爲9,填寫值semaphore[10]爲0;探索候選數semaphore_explore_recover[1--9]全爲0值,probable_explore_recover爲0,探索記錄數組explore[1--9]全爲0
void subtracion(int row,int col,int storage);     //當node[row][col]只有一個候選數可填,且知道這個候選數,調用此函數(非回溯版)(storage要換成k就顯得統一,易理解,但原來是這樣設置的,考慮到只是一個形參生命力只在一個函數內這裏不做改動,它表示node[row][col]填入storage值,並且正要減去所在行列區的其它格的候選數storage
vector<vector<int>> subtracion(int ro        //對第row行的沒有填的m候選數 看看它是不是隻能填在某一格上,或只能填在某一宮的格中,recall=1表示用回溯版
void col_technology(int col,int m,int recall);ll);//當nodew,int col);//當node[row][col]只有一個候選數可填,且知道這個候選數,調用此函數(回溯版)
void call_subtraction(int row,int col,int recam,int recall); [row][col]的一個候選數被減,只剩下一個候選數可填,但又不知道是哪個候選數時調用此函數,recall=1表示用回溯版
void row_technology(int row,int         //對第col列的沒有填的m候選數 看看它是不是隻能填在某一格上,或只能填在某一宮的格中,recall=1表示用回溯版
void room_technology(int i,int m,int recall);      //對第i宮的沒有填的m候選數 看看它是不是隻能填在某一格上,或只能填在宮的某一行或列中,recall=1表示用回溯版
void row_technology(int row ,int recall);      //對第row行所有沒有填的每一個數(即候選數)看看它是不是隻能填在某一格上,或只能填在某一宮的格中,recall=1表示用回溯版
void col_technology(int col,int recall);           //對第col行所有沒有填的每一個數(即候選數)看看它是不是隻能填在某一格上,或只能填在某一宮的格中,recall=1表示用回溯版
void room_technology(int i,int recall);        //對第i宮所有沒有填的每一個數(即候選數)看看它是不是隻能填在某一格上,或只能填在宮的某一行或列中,recall=1表示用回溯版
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中,由於傳址調用所以全局變量v2會被修改。
void print_all();                                                       //輸出當時狀態下的九宮格的所有已填數(輸出到寫出文件中,這個輸出對象可以改的),不管是調試用,還是最後給出正確答案,還是一切要得到中間結果的狀態下都能用到它,
void explore();                                       //當所有技巧或模式都用到極致時(當然也可以不用到極致,有時回溯法要來得更快,或者遍歷模式耗時太長還不如回溯來得快,當然解題高手的興奮點是最短時間發現已經知道的最難的推理模式,或發現新的不同難度係數的推理模式)要用回溯法(回溯法可嵌入技巧,一般以常用到遍歷耗時短的技巧嵌入爲佳),回溯法沒有返回值,沒有參數,形參其實就是全局變量v2,v1,返回值其實是全局變量finished
int test();                               //當題目解完時檢測題目有沒有解錯,方法是每行每列每宮的和都要是45.其實技巧法和回溯法都能用數學證明,只要填滿81個格就一定是正確的,但這個函數耗時不到1毫秒  就保存了下來。
bool  fun( int array[10]);              //數組array的九個數如有重複返回false
bool row_col_room_technology_solve() ;      //最簡單的行列宮互相影響技巧遍歷 ,如果題解出來就返回true,如果解不出來是遍歷後解不出來說明題目中沒有適用的簡單模式
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 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;
   
   
  }
   
}
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;
 vector<int>  not_wrong_add;
 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)
                {
               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;
          not_wrong_add.push_back(10);
                                  v2.push_back(not_wrong_add);
         
          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;
           if(temp[v2.size()-1][3]==400)
            not_wrong_add.pop_back();
                                }
      
       
      
    }
     
         }
  else  if(node[row][j].semaphore[node[row][col].semaphore[10]]==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[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)
                {
                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;
          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);
              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[node[row][col].semaphore[10]]==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=node[row][col].semaphore[10]值,但node[row][col].probable!=0  這是node[i][j]其實被減但會壓入not_wrong_add中最後得不到修復
    if(j==col) continue;
    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)
               {
                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;
                     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);
                         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[node[row][col].semaphore[10]]==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;
}
void call_subtraction(int row,int col,int recall)//recall=0表示技術用,recall=1表示回溯用
{
 if(recall==0)
 {
 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(recall==1)
 {
  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);
  }
 }
}
void row_technology(int row,int m,int recall)//m表示候選數  recall=1表示是要回溯
{
 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)
    {
     if(recall)
     {
      node[row][p[0]].semaphore[k]=0;
      node[row][p[0]].probable--;
      v1.push_back(row);
      v1.push_back(p[0]);
      v1.push_back(k);
      v1.push_back(11);
      v2.push_back(v1);
      v1.clear();
     }
     else
     {
         a[k]=1;//此時不對要減去的候選數進行操作,把它後延是因爲後面還有更誘人的subtraction操作,讓它先進行則更快
               //out_stream<<"行列區互相影響候選數刪減法:"<<char(row-1+'A')<<p[0]<<"應刪"<<k<<"(行"<<char(row-1+'A')<<"只一格能填"<<m<<")。"<<endl;
          //cout<<"行列區互相影響候選數刪減法:"<<char(row-1+'A')<<p[0]<<"應刪"<<k<<"(行"<<char(row-1+'A')<<"只一格能填"<<m<<")。"<<endl;
     }
    }
            for(int k=m+1;k<=9;k++)
    if(node[row][p[0]].semaphore[k]==1)
    {
     if(recall)
     {
      node[row][p[0]].semaphore[k]=0;
      node[row][p[0]].probable--;
      v1.push_back(row);
      v1.push_back(p[0]);
      v1.push_back(k);
      v1.push_back(11);
      v2.push_back(v1);
      v1.clear();
     }
     else
     {
         a[k]=1;//此時不對要減去的候選數進行操作,把它後延是因爲後面還有更誘人的subtraction操作,讓它先進行則更快
               //out_stream<<"行列區互相影響候選數刪減法:"<<char(row-1+'A')<<p[0]<<"應刪"<<k<<"(行"<<char(row-1+'A')<<"只一格能填"<<m<<")。"<<endl;
          //cout<<"行列區互相影響候選數刪減法:"<<char(row-1+'A')<<p[0]<<"應刪"<<k<<"(行"<<char(row-1+'A')<<"只一格能填"<<m<<")。"<<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,recall);
     col_technology(p[0],k,recall);
     room_technology(room(row,p[0]),k,recall);
    }
            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<<"(行"<<char(row-1+'A')<<"對宮"<<room(row,p[0])<<"的影響)。"<<endl;
       //cout<<"行列區互相影響候選數刪減法:"<<char(i-1+'A')<<j<<"應刪"<<m<<"(行"<<char(row-1+'A')<<"對宮"<<room(row,p[0])<<"的影響)。"<<endl;
       node[i][j].semaphore[m]=0;
       node[i][j].probable--;
       if(node[i][j].probable==1)
        call_subtraction(i,j,recall);//
       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<<"(行"<<char(row-1+'A')<<"對宮"<<room(row,p[0])<<"的影響)。"<<endl;
       //cout<<"行列區互相影響候選數刪減法:"<<char(i-1+'A')<<j<<"應刪"<<m<<"(行"<<char(row-1+'A')<<"對宮"<<room(row,p[0])<<"的影響)。"<<endl;
       node[i][j].semaphore[m]=0;
       node[i][j].probable--;
       if(node[i][j].probable==1)
        call_subtraction(i,j,recall);//
       a[j-k2]=1;
       if(a[3]==0)  a[3]=i;
       else if(a[3]!=i)  a[4]=i;
      }
      if(a[0]==1)  col_technology(k2,m,recall);
      if(a[1]==1)  col_technology(k2+1,m,recall);
      if(a[2]==1)  col_technology(k2+2,m,recall);
      if(a[3]!=0)  row_technology(a[3],m,recall);
      if(a[4]!=0)  row_technology(a[4],m,recall);
   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<<"(行"<<char(row-1+'A')<<"對宮"<<room(row,p[0])<<"的影響)。"<<endl;
       //cout<<"行列區互相影響候選數刪減法:"<<char(i-1+'A')<<j<<"應刪"<<m<<"(行"<<char(row-1+'A')<<"對宮"<<room(row,p[0])<<"的影響)。"<<endl;
       node[i][j].semaphore[m]=0;
       node[i][j].probable--;
       if(node[i][j].probable==1)
        call_subtraction(i,j,recall);//
       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<<"(行"<<char(row-1+'A')<<"對宮"<<room(row,p[0])<<"的影響)。"<<endl;
       //cout<<"行列區互相影響候選數刪減法:"<<char(i-1+'A')<<j<<"應刪"<<m<<"(行"<<char(row-1+'A')<<"對宮"<<room(row,p[0])<<"的影響)。"<<endl;
       node[i][j].semaphore[m]=0;
       node[i][j].probable--;
       if(node[i][j].probable==1)
        call_subtraction(i,j,recall);//
       a[j-k2]=1;
       if(a[3]==0)  a[3]=i;
       else if(a[3]!=i)  a[4]=i;
      }
      if(a[0]==1)  col_technology(k2,m,recall);
      if(a[1]==1)  col_technology(k2+1,m,recall);
      if(a[2]==1)  col_technology(k2+2,m,recall);
      if(a[3]!=0)  row_technology(a[3],m,recall);
      if(a[4]!=0)  row_technology(a[4],m,recall);
   delete[] a;
   }
  }
 delete[] p;
}
void col_technology(int col,int m,int recall)//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<<"(列"<<col<<"只一格能填"<<m<<")。"<<endl;
     //cout<<"行列區互相影響候選數刪減法:"<<char(p[0]-1+'A')<<col<<"應刪"<<k<<"(列"<<col<<"只一格能填"<<m<<")。"<<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<<"(列"<<col<<"只一格能填"<<m<<")。"<<endl;
     //cout<<"行列區互相影響候選數刪減法:"<<char(p[0]-1+'A')<<col<<"應刪"<<k<<"(列"<<col<<"只一格能填"<<m<<")。"<<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,recall);
     col_technology(col,k,recall);
     room_technology(room(p[0],col),k,recall);
    }
            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<<"(列"<<col<<"對宮"<<room(p[0],col)<<"的影響)。"<<endl;
       //cout<<"行列區互相影響候選數刪減法:"<<char(i-1+'A')<<j<<"應刪"<<m<<"(列"<<col<<"對宮"<<room(p[0],col)<<"的影響)。"<<endl;
       node[i][j].semaphore[m]=0;
       node[i][j].probable--;
       if(node[i][j].probable==1)
        call_subtraction(i,j,recall);//
       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<<"(列"<<col<<"對宮"<<room(p[0],col)<<"的影響)。"<<endl;
       //cout<<"行列區互相影響候選數刪減法:"<<char(i-1+'A')<<j<<"應刪"<<m<<"(列"<<col<<"對宮"<<room(p[0],col)<<"的影響)。"<<endl;
       node[i][j].semaphore[m]=0;
       node[i][j].probable--;
       if(node[i][j].probable==1)
        call_subtraction(i,j,recall);//
       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,recall);
      if(a[1]==1)  row_technology(k1+1,m,recall);
      if(a[2]==1)  row_technology(k1+2,m,recall);
      if(a[3]!=0)  col_technology(a[3],m,recall);
      if(a[4]!=0)  col_technology(a[4],m,recall);
   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<<"(列"<<col<<"對宮"<<room(p[0],col)<<"的影響)。"<<endl;
       //cout<<"行列區互相影響候選數刪減法:"<<char(i-1+'A')<<j<<"應刪"<<m<<"(列"<<col<<"對宮"<<room(p[0],col)<<"的影響)。"<<endl;
       node[i][j].semaphore[m]=0;
       node[i][j].probable--;
       if(node[i][j].probable==1)
        call_subtraction(i,j,recall);//
       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<<"(列"<<col<<"對宮"<<room(p[0],col)<<"的影響)。"<<endl;
       //cout<<"行列區互相影響候選數刪減法:"<<char(i-1+'A')<<j<<"應刪"<<m<<"(列"<<col<<"對宮"<<room(p[0],col)<<"的影響)。"<<endl;
       node[i][j].semaphore[m]=0;
       node[i][j].probable--;
       if(node[i][j].probable==1)
        call_subtraction(i,j,recall);//
       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,recall);
      if(a[1]==1)  row_technology(k1+1,m,recall);
      if(a[2]==1)  row_technology(k1+2,m,recall);
      if(a[3]!=0)  col_technology(a[3],m,recall);
      if(a[4]!=0)  col_technology(a[4],m,recall);
   delete[] a;
   }
  }
 delete[] p;
}
void room_technology(int i,int m,int recall)//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>> v3;
  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);
       v3.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[v3[0][0]][v3[0][1]].semaphore[k]==1)
    {
     p[k]=1;//此時不對要減去的候選數進行操作,把它後延是因爲後面還有更誘人的subtraction操作,讓它先進行則更快
           //out_stream<<"行列區互相影響候選數刪減法:"<<char(v3[0][0]-1+'A')<<v3[0][1]<<"應刪"<<k<<"(宮"<<i<<"只一格能填"<<m<<")。"<<endl;
     //cout<<"行列區互相影響候選數刪減法:"<<char(v3[0][0]-1+'A')<<v3[0][1]<<"應刪"<<k<<"(宮"<<i<<"只一格能填"<<m<<")。"<<endl;
    }
            for(int k=m+1;k<=9 ;k++)
    if(node[v3[0][0]][v3[0][1]].semaphore[k]==1)
    {
     p[k]=1;//此時不對要減去的候選數進行操作,把它後延是因爲後面還有更誘人的subtraction操作,讓它先進行則更快
           //out_stream<<"行列區互相影響候選數刪減法:"<<char(v3[0][0]-1+'A')<<v3[0][1]<<"應刪"<<k<<"(宮"<<i<<"只一格能填"<<m<<")。"<<endl;
     //cout<<"行列區互相影響候選數刪減法:"<<char(v3[0][0]-1+'A')<<v3[0][1]<<"應刪"<<k<<"(宮"<<i<<"只一格能填"<<m<<")。"<<endl;
    }
   for(int k=1;k<=9;k++)
    node[v3[0][0]][v3[0][1]].semaphore[k]=0;
   node[v3[0][0]][v3[0][1]].probable=0;
   node[v3[0][0]][v3[0][1]].semaphore[10]=m;
   //out_stream<<"唯一數:"<<char(v3[0][0]-1+'A')<<v3[0][1]<<"應填"<<m<<"。"<<endl;
   //cout<<"唯一數:"<<char(v3[0][0]-1+'A')<<v3[0][1]<<"應填"<<m<<"。"<<endl;
   subtraction(v3[0][0],v3[0][1],m);
   for(int k=1;k<=9;k++)
    if(p[k]==1)
    {
     row_technology(v3[0][0],k,recall);
     col_technology(v3[0][1],k,recall);
     room_technology(room(v3[0][0],v3[0][1]),k,recall);
    }
            delete[] p;
  }
     else if(sum==2)//非回溯
  {
   if(v3[0][0]==v3[1][0])
   {
    int* p=new int[2];//存放它可能影響的兩個宮
    p[0]=0;p[1]=0;
    for(int col=1;col<=k2-1;col++)
     if(node[v3[0][0]][col].semaphore[m]==1)
     {
      //out_stream<<"行列區互相影響候選數刪減法:"<<char(v3[0][0]-1+'A')<<col<<"應刪"<<m<<"(宮"<<i<<"對行"<<char(v3[0][0]-1+'A')<<"的影響)。"<<endl;
      //cout<<"行列區互相影響候選數刪減法:"<<char(v3[0][0]-1+'A')<<col<<"應刪"<<m<<"(宮"<<i<<"對行"<<char(v3[0][0]-1+'A')<<"的影響)。"<<endl;
      node[v3[0][0]][col].semaphore[m]=0;//非回溯,技巧是(區塊影響行列)候選數刪減法
      node[v3[0][0]][col].probable--;
      if(node[v3[0][0]][col].probable==1)
       call_subtraction(v3[0][0],col,recall);
      col_technology(col,m,recall);//這裏的調用可以迅速縮短得到結果時間,不管是正確還是錯誤
     if(p[0]==0) p[0]=room(v3[0][0],col);
     else if( p[0]!=room(v3[0][0],col))    p[1]=room(v3[0][0],col);
     }
               for(int col=k2+3;col<=9;col++)
     if(node[v3[0][0]][col].semaphore[m]==1)
     {
      //out_stream<<"行列區互相影響候選數刪減法:"<<char(v3[0][0]-1+'A')<<col<<"應刪"<<m<<"(宮"<<i<<"對行"<<char(v3[0][0]-1+'A')<<"的影響)。"<<endl;
      //cout<<"行列區互相影響候選數刪減法:"<<char(v3[0][0]-1+'A')<<col<<"應刪"<<m<<"(宮"<<i<<"對行"<<char(v3[0][0]-1+'A')<<"的影響)。"<<endl;
      node[v3[0][0]][col].semaphore[m]=0;//非回溯,技巧是(區塊影響行列)候選數刪減法
      node[v3[0][0]][col].probable--;
      if(node[v3[0][0]][col].probable==1)
       call_subtraction(v3[0][0],col,recall);
      col_technology(col,m,recall);//這裏的調用可以迅速縮短得到結果時間,不管是正確還是錯誤
     if(p[0]==0) p[0]=room(v3[0][0],col);
     else if( p[0]!=room(v3[0][0],col))    p[1]=room(v3[0][0],col);
     }
               if(p[0]!=0)  room_technology(p[0],m,recall);//p[0]!=0說明room p[0]中的候選數v[i]被減掉至少一個,如果剪掉兩個就應該把這個語句放在for循環外面
      if(p[1]!=0)  room_technology(p[1],m,recall);
      delete[] p;
   }
   else if(v3[0][1]==v3[1][1])
   {
    int* p=new int[2];//存放它可能影響的兩個宮
    p[0]=0;p[1]=0;
    for(int row=1;row<=k1-1;row++)
     if(node[row][v3[0][1]].semaphore[m]==1)
     {
      //out_stream<<"行列區互相影響候選數刪減法:"<<char(row-1+'A')<<v3[0][1]<<"應刪"<<m<<"(宮"<<i<<"對列"<<v3[0][1]<<"的影響)。"<<endl;
      //cout<<"行列區互相影響候選數刪減法:"<<char(row-1+'A')<<v3[0][1]<<"應刪"<<m<<"(宮"<<i<<"對列"<<v3[0][1]<<"的影響)。"<<endl;
      node[row][v3[0][1]].semaphore[m]=0;//非回溯,技巧是(區塊影響行列)候選數刪減法
      node[row][v3[0][1]].probable--;
      if(node[row][v3[0][1]].probable==1)
       call_subtraction(row,v3[0][1],recall);
      row_technology(row,m,recall);//這裏的調用可以迅速縮短得到結果時間,不管是正確還是錯誤
     if(p[0]==0) p[0]=room(row,v3[0][1]);
     else if( p[0]!=room(row,v3[0][1]))    p[1]=room(row,v3[0][1]);
     }
               for(int row=k1+3;row<=9;row++)
     if(node[row][v3[0][1]].semaphore[m]==1)
     {
      //out_stream<<"行列區互相影響候選數刪減法:"<<char(row-1+'A')<<v3[0][1]<<"應刪"<<m<<"(宮"<<i<<"對列"<<v3[0][1]<<"的影響)。"<<endl;
      //cout<<"行列區互相影響候選數刪減法:"<<char(row-1+'A')<<v3[0][1]<<"應刪"<<m<<"(宮"<<i<<"對列"<<v3[0][1]<<"的影響)。"<<endl;
      node[row][v3[0][1]].semaphore[m]=0;//非回溯,技巧是(區塊影響行列)候選數刪減法
      node[row][v3[0][1]].probable--;
      if(node[row][v3[0][1]].probable==1)
       call_subtraction(row,v3[0][1],recall);
      row_technology(row,m,recall);//這裏的調用可以迅速縮短得到結果時間,不管是正確還是錯誤
     if(p[0]==0) p[0]=room(row,v3[0][1]);
     else if( p[0]!=room(row,v3[0][1]))    p[1]=room(row,v3[0][1]);
     }
               if(p[0]!=0)  room_technology(p[0],m,recall);//p[0]!=0說明room p[0]中的候選數v[i]被減掉至少一個,如果剪掉兩個就應該把這個語句放在for循環外面
      if(p[1]!=0)  room_technology(p[1],m,recall);
      delete[] p;
   }
  }
  else if(sum==3)//非回溯
  {
   if(v3[0][0]==v3[1][0] && v3[0][0]==v3[2][0] )
   {
    int* p=new int[2];//存放它可能影響的兩個宮
    p[0]=0;p[1]=0;
    for(int col=1;col<=k2-1;col++)
     if(node[v3[0][0]][col].semaphore[m]==1)
     {
      //out_stream<<"行列區互相影響候選數刪減法:"<<char(v3[0][0]-1+'A')<<col<<"應刪"<<m<<"(宮"<<i<<"對行"<<char(v3[0][0]-1+'A')<<"的影響)。"<<endl;
      //cout<<"行列區互相影響候選數刪減法:"<<char(v3[0][0]-1+'A')<<col<<"應刪"<<m<<"(宮"<<i<<"對行"<<char(v3[0][0]-1+'A')<<"的影響)。"<<endl;
      node[v3[0][0]][col].semaphore[m]=0;//非回溯,技巧是(區塊影響行列)候選數刪減法
      node[v3[0][0]][col].probable--;
      if(node[v3[0][0]][col].probable==1)
       call_subtraction(v3[0][0],col,recall);
      col_technology(col,m,recall);//這裏的調用可以迅速縮短得到結果時間,不管是正確還是錯誤
     if(p[0]==0) p[0]=room(v3[0][0],col);
     else if( p[0]!=room(v3[0][0],col))    p[1]=room(v3[0][0],col);
     }
               for(int col=k2+3;col<=9;col++)
     if(node[v3[0][0]][col].semaphore[m]==1)
     {
      //out_stream<<"行列區互相影響候選數刪減法:"<<char(v3[0][0]-1+'A')<<col<<"應刪"<<m<<"(宮"<<i<<"對行"<<char(v3[0][0]-1+'A')<<"的影響)。"<<endl;
      //cout<<"行列區互相影響候選數刪減法:"<<char(v3[0][0]-1+'A')<<col<<"應刪"<<m<<"(宮"<<i<<"對行"<<char(v3[0][0]-1+'A')<<"的影響)。"<<endl;
      node[v3[0][0]][col].semaphore[m]=0;//非回溯,技巧是(區塊影響行列)候選數刪減法
      node[v3[0][0]][col].probable--;
      if(node[v3[0][0]][col].probable==1)
       call_subtraction(v3[0][0],col,recall);
      col_technology(col,m,recall);//這裏的調用可以迅速縮短得到結果時間,不管是正確還是錯誤
     if(p[0]==0) p[0]=room(v3[0][0],col);
     else if( p[0]!=room(v3[0][0],col))    p[1]=room(v3[0][0],col);
     }
               if(p[0]!=0)  room_technology(p[0],m,recall);//p[0]!=0說明room p[0]中的候選數v[i]被減掉至少一個,如果剪掉兩個就應該把這個語句放在for循環外面
      if(p[1]!=0)  room_technology(p[1],m,recall);
      delete[] p;
   }
   else if(v3[0][1]==v3[1][1] && v3[0][1]==v3[2][1])
   {
    int* p=new int[2];//存放它可能影響的兩個宮
    p[0]=0;p[1]=0;
    for(int row=1;row<=k1-1;row++)
     if(node[row][v3[0][1]].semaphore[m]==1)
     {
      //out_stream<<"行列區互相影響候選數刪減法:"<<char(row-1+'A')<<v3[0][1]<<"應刪"<<m<<"(宮"<<i<<"對列"<<v3[0][1]<<"的影響)。"<<endl;
      //cout<<"行列區互相影響候選數刪減法:"<<char(row-1+'A')<<v3[0][1]<<"應刪"<<m<<"(宮"<<i<<"對列"<<v3[0][1]<<"的影響)。"<<endl;
      node[row][v3[0][1]].semaphore[m]=0;//非回溯,技巧是(區塊影響行列)候選數刪減法
      node[row][v3[0][1]].probable--;
      if(node[row][v3[0][1]].probable==1)
       call_subtraction(row,v3[0][1],recall);
      row_technology(row,m,recall);//這裏的調用可以迅速縮短得到結果時間,不管是正確還是錯誤
     if(p[0]==0) p[0]=room(row,v3[0][1]);
     else if( p[0]!=room(row,v3[0][1]))    p[1]=room(row,v3[0][1]);
     }
               for(int row=k1+3;row<=9;row++)
     if(node[row][v3[0][1]].semaphore[m]==1)
     {
      //out_stream<<"行列區互相影響候選數刪減法:"<<char(row-1+'A')<<v3[0][1]<<"應刪"<<m<<"(宮"<<i<<"對列"<<v3[0][1]<<"的影響)。"<<endl;
      //cout<<"行列區互相影響候選數刪減法:"<<char(row-1+'A')<<v3[0][1]<<"應刪"<<m<<"(宮"<<i<<"對列"<<v3[0][1]<<"的影響)。"<<endl;
      node[row][v3[0][1]].semaphore[m]=0;//非回溯,技巧是(區塊影響行列)候選數刪減法
      node[row][v3[0][1]].probable--;
      if(node[row][v3[0][1]].probable==1)
       call_subtraction(row,v3[0][1],recall);
      row_technology(row,m,recall);//這裏的調用可以迅速縮短得到結果時間,不管是正確還是錯誤
     if(p[0]==0) p[0]=room(row,v3[0][1]);
     else if( p[0]!=room(row,v3[0][1]))    p[1]=room(row,v3[0][1]);
     }
               if(p[0]!=0)  room_technology(p[0],m,recall);//p[0]!=0說明room p[0]中的候選數v[i]被減掉至少一個,如果剪掉兩個就應該把這個語句放在for循環外面
      if(p[1]!=0)  room_technology(p[1],m,recall);
      delete[] p;
   }
  }
 v3.clear();
}
void row_technology(int row ,int recall)
{
 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],recall);
 v.clear();
 loop:  ;
}
void col_technology(int col,int recall)
{
 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--)
     col_technology(col,v[i],recall);
 v.clear();
 loop:  ;
}
void room_technology(int i,int recall)
{
 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],recall);
 v.clear();
 loop: ;
}
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 row_col_room_technology_solve()
{
 int j;
 do{
   j=count_candidate_number();
     for(int i=1;i<=9;i++)
       {
       row_technology(i,0);
       col_technology(i,0);
       room_technology(i,0);
        }
 }while(j!=count_candidate_number());
 if(count_candidate_number())
  return (false);
 else return (true);
}
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;
}
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;
  }
bool 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 (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--;
 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  )//這一行最後面那個函數是調試後打的補丁  用處是不該恢復的不恢復
            {
            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 )
            {
            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 )
            {
            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 )
        {
         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 )
         {
             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 )
                {
                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 )
               {
            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 )
         {
             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 )
                {
                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 )
               {
            node[row1][j].semaphore[storage]=1;
            node[row1][j].probable+=1;
            }
       break;  
     }
 for(int i=1;  i<=(not_wrong_add.size()-1)/2;   i++)
 {
  if(node[not_wrong_add[2*i-2]][not_wrong_add[2*i-1]].semaphore[storage]==0)
  {
   node[not_wrong_add[2*i-2]][not_wrong_add[2*i-1]].semaphore[storage]=1;
      node[not_wrong_add[2*i-2]][not_wrong_add[2*i-1]].probable++;
  }
 }

 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;
  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][v2_transcript[v2_transcript.size()-1].size()-1]==400)//  && 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_transcript[0][3]==10  || v2_transcript[0][3]==20 || v2_transcript[0][3]==30) && v2.size()>1)
 {
  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_transcript[0][3]==10  || v2_transcript[0][3]==20 || v2_transcript[0][3]==30) && v2.size()==1)
 {
  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_transcript.size()==2 && v2.size()==1 && v2_transcript[0][3]==400 && v2_transcript[1][v2_transcript[1].size()-1]==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_transcript[0][3]==100 && v2_transcript[1][v2_transcript[1].size()-1]==100)  || (v2_transcript[0][3]==200 && v2_transcript[1][v2_transcript[1].size()-1]==200) || (v2_transcript[0][3]==300 && v2_transcript[1][v2_transcript[1].size()-1]==300)) && v2_transcript.size()==2  && v2.size()>1)
 {
  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[i][3]==0 && ((v2_transcript[0][3]==100 && v2_transcript[1][v2_transcript[1].size()-1]==100)  || (v2_transcript[0][3]==200 && v2_transcript[1][v2_transcript[1].size()-1]==200) || (v2_transcript[0][3]==300 && v2_transcript[1][v2_transcript[1].size()-1]==300)) && v2_transcript.size()==2)
 {
  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
 }
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;
      switch(room(min_probable_node.row,min_probable_node.col))
      {
         case 1: for( int i=1;i<=3;i++)
            for(int j=1;j<=3;j++)
            {
             if(node[i][j].semaphore[10]==k)
                goto loop;
               } break;
         case 2:  for( int i=1;i<=3;i++)
            for(int j=4;j<=6;j++)
            {
             if(node[i][j].semaphore[10]==k)
                goto loop;
               } break;
         case 3:  for( int i=1;i<=3;i++)
            for(int j=7;j<=9;j++)
            {
             if(node[i][j].semaphore[10]==k)
                goto loop;
               } break;
         case 4:  for( int i=4;i<=6;i++)
            for(int j=1;j<=3;j++)
            {
             if(node[i][j].semaphore[10]==k)
                goto loop;
               } break;
         case 5: for( int i=4;i<=6;i++)
            for(int j=4;j<=6;j++)
            {
             if(node[i][j].semaphore[10]==k)
                goto loop;
               } break;
         case 6:  for( int i=4;i<=6;i++)
            for(int j=7;j<=9;j++)
            {
             if(node[i][j].semaphore[10]==k)
                goto loop;
               } break;
         case 7: for( int i=7;i<=9;i++)
            for(int j=1;j<=3;j++)
            {
             if(node[i][j].semaphore[10]==k)
                goto loop;
               } break;
         case 8:  for( int i=7;i<=9;i++)
            for(int j=4;j<=6;j++)
            {
             if(node[i][j].semaphore[10]==k)
                goto loop;
               } break;
         case 9: for( int i=7;i<=9;i++)
            for(int j=7;j<=9;j++)
            {
             if(node[i][j].semaphore[10]==k)
                goto loop;
               } break;
      }
      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;   
        //print_all(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 main()
{
 int information_number=0;
 long time1;
 out_stream.open("d:\\c++\\數獨12\\question\\question475.txt");
 time1=clock();
 srand(time(0));
 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];
 }
 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();   finished=0;
  continue;
 }
  row_col_room_technology_solve();
 if(finished==81 && test())
 {
  v2.clear(); v3.clear();v1.clear();   finished=0;
  continue;
 }
 explore();
 if(test())  ;
 else   { out_stream<<"測試第"<<op<<"個題目失敗"<<endl;  print_all(1); print_all();}
 v2.clear(); v3.clear();v1.clear();  finished=0;
 }
 time1=clock()-time1;
 out_stream<<"耗時"<<time1/1000<<"秒"<<time1%1000<<"毫秒"<<endl;
 out_stream.close();
 }

 

 

 

發佈了12 篇原創文章 · 獲贊 0 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章