全局变量精确恢复精简版3秒

来源:互联网 发布:海王星对讲机写频软件 编辑:程序博客网 时间:2024/05/04 23:00

QQ及邮箱:1 4 2 3 1 7 3 7 8 3 @qq.com 欢迎吹毛求疵。代码混乱黏贴到vc2010就很工整。

//代码修改后可以依次输出填数顺序,哪一个空填了哪一个数,保存在vstart1中
//用全局变量
#include<iostream>
#include<fstream>
#include<vector>
#include<time.h>
#include<cstdlib>
using namespace std;
int probable[9][9],storage[9][9],semaphore[9][9][9];

int finished=0;
ofstream out_stream;
vector<int>  v1;
vector<vector<int>> v2,success,vstart,vstart1;//vstart1用来存储 填格子的先后顺序  (i,j) 填了k
vector<vector<vector<int>>>    v3;


void fills_up();
bool in_vstart_or_v3(int row,int col,int number);
bool row_col_relation_have_the_number(int row,int col,int number);
void add(int row1,int col1,int row2,int col2,int storage,int semaphore);//semaphore的值为100,200,300,400  表示从四个方向上恢复
vector<vector<int>> subtraction(int row,int col,int sto);
void addv2(vector<vector<int>> & v2);
void print_all();
void dfs( );
int test();
int fun( int array[10]);


void fills_up()
{
 for(int i=0;i<=8;i++)
  for(int j=0;j<=8;j++)
  {
   for(int k=0;k<=8;k++)
        semaphore[i][j][k]=1;
            storage[i][j]=0;
   probable[i][j]=9;
  }
}
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=0;j<=8;j++)
          if(storage[row][j]==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=0;i<=8;i++)
          if(storage[i][col]==number)
               if(in_vstart_or_v3(i,col,number))
      return (true);    
 for(int i=row/3*3;i<=row/3*3+2;i++)
  for( int j=col/3*3;j<=col/3*3+2;j++)
               if(storage[i][j]==number)
      if(in_vstart_or_v3(i,j,number))
          return (true);
 return (false);  
 }
void add(int row1,int col1,int row2,int col2,int sto,int sem)//semaphore的值为100,200,300,400  表示从四个方向上恢复
{
 vstart1.pop_back();
 finished--;
 semaphore[row1][col1][sto-1]=1;
 probable[row1][col1]+=1;   //node[row][col].storage的值最后变回0,下面恢复三个区域要用到这个值。
 storage[row1][col1]=0;
 switch(sem)
         {
        case 10:
        case 100:   for(int j=col2;j>=0;j--)
                            if(semaphore[row1][j][sto-1]==0 && probable[row1][j]!=0 && !row_col_relation_have_the_number(row1,j,sto))//这一行最后面那个函数是调试后打的补丁  用处是不该恢复的不恢复
            {
            semaphore[row1][j][sto-1]=1;
            probable[row1][j]+=1;
        }  break;
     case 20:
     case 200:   for(int i=row2;i>=0;i--)
                            if(semaphore[i][col2][sto-1]==0 && probable[i][col2]!=0 && !row_col_relation_have_the_number(i,col2,sto))
            {
            semaphore[i][col2][sto-1]=1;
            probable[i][col2]+=1;
        }
      for(int j=8;j>=0;j--)
                            if(semaphore[row1][j][sto-1]==0 && probable[row1][j]!=0 && !row_col_relation_have_the_number(row1,j,sto))//这一行最后面那个函数是调试后打的补丁  用处是不该恢复的不恢复
            {
            semaphore[row1][j][sto-1]=1;
            probable[row1][j]+=1;
        }  break;
     case 30:
     case 300:    for(int j=col2;j>=col2/3*3;j--)
        if(semaphore[row2][j][sto-1]==0 && probable[row2][j]!=0 && !row_col_relation_have_the_number(row2,j,sto))
        {
         semaphore[row2][j][sto-1]=1;
         probable[row2][j]+=1;
        }
       for(int i=row2-1;i>=row2/3*3;i--)
        for(int j=col2/3*3+2;j>=col2/3*3;j--)
             if(semaphore[i][j][sto-1]==0 && probable[i][j]!=0 && !row_col_relation_have_the_number(i,j,sto))
         {
             semaphore[i][j][sto-1]=1;
             probable[i][j]+=1;
         }
      for(int i=8;i>=0;i--)
                            if(semaphore[i][col1][sto-1]==0 && probable[i][col1]!=0 && !row_col_relation_have_the_number(i,col1,sto))
            {
            semaphore[i][col1][sto-1]=1;
            probable[i][col1]+=1;
        }
      for(int j=8;j>=0;j--)
                            if(semaphore[row1][j][sto-1]==0 && probable[row1][j]!=0 && !row_col_relation_have_the_number(row1,j,sto))//这一行最后面那个函数是调试后打的补丁  用处是不该恢复的不恢复
            {
            semaphore[row1][j][sto-1]=1;
            probable[row1][j]+=1;
        }  break;
      case 400:    for(int i=row2/3*3+2;i>=row2/3*3;i--)
        for(int j=col2/3*3+2;j>=col2/3*3;j--)
             if(semaphore[i][j][sto-1]==0 && probable[i][j]!=0 && !row_col_relation_have_the_number(i,j,sto))
         {
             semaphore[i][j][sto-1]=1;
             probable[i][j]+=1;
         }
      for(int i=8;i>=0;i--)
                            if(semaphore[i][col1][sto-1]==0 && probable[i][col1]!=0 && !row_col_relation_have_the_number(i,col1,sto))
            {
            semaphore[i][col1][sto-1]=1;
            probable[i][col1]+=1;
        }
      for(int j=8;j>=0;j--)
                            if(semaphore[row1][j][sto-1]==0 && probable[row1][j]!=0 && !row_col_relation_have_the_number(row1,j,sto))//这一行最后面那个函数是调试后打的补丁  用处是不该恢复的不恢复
            {
            semaphore[row1][j][sto-1]=1;
            probable[row1][j]+=1;
        }  break;
     } 
}
/*void add(int row1,int col1,int row2,int col2,int storage,int semaphore)//semaphore的值为100,200,300,400  表示从四个方向上恢复
{
 vstart1.pop_back();
 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;  //调试发现的,后来加上
    }
} */

vector<vector<int>> subtraction(int row,int col,int sto)
{
 finished++;
 if(finished==81)  return success;
 vector<vector<int>>   temp;
 for(int j=0;j<=8;j++) 
  if(semaphore[row][j][sto-1]==1 && probable[row][j]!=0)
   {
    semaphore[row][j][sto-1]=0;    //把节点中不能填的点排除
    probable[row][j]-=1;                                             //probable即可能填的数目减1
    if(probable[row][j]==1)        
    {
          for(int k=0;k<=8;k++)
           if(semaphore[row][j][k]==1)
           {
           for(int m=0;m<=8;m++)
               if(k+1==storage[row][m] && 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=0;m<=8;m++)
               if(k+1==storage[m][j] && 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/3*3;m<=row/3*3+2;m++)
            for(int n=j/3*3;n<=j/3*3+2;n++)
                 if(k+1==storage[m][n] && !(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;
                  } 
           storage[row][j]=k+1;
           semaphore[row][j][k]=0;
           probable[row][j]=0;
           v1.push_back(row);
              v1.push_back(j);
              v1.push_back(k+1);
           vstart1.push_back(v1);
              v1.push_back(10);
              v2.push_back(v1);
              v1.clear();
           temp=subtraction(row,j,k+1);
              if(temp==success)    return success;
              if(temp[v2.size()-1][3]>30 && temp[v2.size()-1][3]!=400 )   
               goto  loop;
                                }
    }
         }
 for(int i=0;i<=8;i++) 
  if(semaphore[i][col][sto-1]==1 && probable[i][col]!=0)
   {
    semaphore[i][col][sto-1]=0;    //把节点中不能填的点排除
    probable[i][col]-=1;                                             //probable即可能填的数目减1
    if(probable[i][col]==1)        
    {
          for(int k=0;k<=8;k++)
           if(semaphore[i][col][k]==1)
           {
            for(int m=0;m<=8;m++)
               if(k+1==storage[i][m] && 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=0;m<=8;m++)
               if(k+1==storage[m][col] && 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/3*3;m<=i/3*3+2;m++)
          for(int n=col/3*3;n<=col/3*3+2;n++)
                if(k+1==storage[m][n] && !(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;
                  } 
           storage[i][col]=k+1;
           semaphore[i][col][k]=0;
           probable[i][col]=0;
           v1.push_back(i);
              v1.push_back(col);
              v1.push_back(k+1);
           vstart1.push_back(v1);
              v1.push_back(20);
              v2.push_back(v1);
              v1.clear();
                 temp=subtraction(i,col,k+1);
              if(temp==success)    return success;
              if(temp[v2.size()-1][3]>30 && temp[v2.size()-1][3]!=400 )   
               goto  loop;
                                }
    }
         }
     for(int i=row/3*3;i<=row/3*3+2;i++)
         for(int j=col/3*3;j<=col/3*3+2;j++)
    if(semaphore[i][j][sto-1]==1 && probable[i][j]!=0)
                   {
                     semaphore[i][j][sto-1]=0;    //把节点中不能填的点排除
                      probable[i][j]-=1;                                             //probable即可能填的数目减1
                     if(probable[i][j]==1)        
                        {
                        for(int k=0;k<=8;k++)
                          if(semaphore[i][j][k]==1)
                         {
             for(int m=0;m<=8;m++)
                  {
               if(storage[i][m]==k+1 && 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=0;m<=8;m++)
                  {
               if(storage[m][j]==k+1 && 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=i/3*3;m<=i/3*3+2;m++)
                                                  for( int n=j/3*3;n<=j/3*3+2;n++)
                                                       {
                if(k+1==storage[m][n] && !(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;
               }
              }             
               storage[i][j]=k+1;
                      semaphore[i][j][k]=0;
                      probable[i][j]=0;
                      v1.push_back(i);
                         v1.push_back(j);
                         v1.push_back(k+1);
             vstart1.push_back(v1);
                         v1.push_back(30);
                         v2.push_back(v1);
                         v1.clear();
                            temp=subtraction(i,j,k+1);
                         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 addv2(vector<vector<int>> & v2)
 {
  vector<vector<int>>  v2_transcript;
  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);
      v2.pop_back();
      v2_transcript.pop_back();
      continue;
        }
  if(0<v2_transcript[v2_transcript.size()-1][3] && v2_transcript[v2_transcript.size()-1][3]<400)//probable value  10,20,30,100,200,300
        {
   add(v2[i][0],v2[i][1],v2_transcript[v2_transcript.size()-1][0],v2_transcript[v2_transcript.size()-1][1],v2[i][2],v2_transcript[v2_transcript.size()-1][3]);
      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<<storage[i-1][j-1]<<" ";
     if(j%3==0) out_stream<<"   ";
     }   
    out_stream<<endl;
    if(i%3==0)  out_stream<<endl;
     }
   out_stream<<endl<<endl;
}
void dfs( )
 {
      int row,col,pro,recover_probable;
   int recover[10];
      pro=10;
      for(int i=8;i>=0;i--)
         {
         for(int j=8 ;j>=0;j--)
            {
       if(pro>=probable[i][j] && probable[i][j]!=0  )
      { pro=probable[i][j];
      row=i;
      col=j;
      }
            }
         }
       for(int k=0;k<=8;k++)
                   {
           if(semaphore[row][col][k]==1)
          { 
         for(int r=0;r<=8;r++)
              recover[r]=semaphore[row][col][r];
        recover_probable=probable[row][col];
        for(int r=0;r<=8;r++)
                                 semaphore[row][col][r]=0;
                       probable[row][col]=0;
                       storage[row][col]=k+1;
        v1.push_back(row);
        v1.push_back(col);
                    v1.push_back(k+1);
        vstart1.push_back(v1);
        v1.push_back(0);
        v2.push_back(v1);
                    v1.clear();
        if(subtraction(row,col,k+1)==success)
              return;
           else if(v2[v2.size()-1][3]>30 && v2[v2.size()-1][3]!=400) 
         {
        addv2(v2);
              v2.clear();
              for(int r=0;r<=8;r++)
                 semaphore[row][col][r]=recover[r];
              probable[row][col]=recover_probable;
       }
           else  
            {
           v3.push_back(v2);
           v2.clear();
           dfs();
        if(finished==81)
         return;
        addv2(v3[v3.size()-1]);
        v3.pop_back();
              for(int r=0;r<=8;r++)
                 semaphore[row][col][r]=recover[r];
              probable[row][col]=recover_probable;
            }
      }
    }  
}
int test()
  {
   int sum=0,i,j,k;
   for(int i=0;i<=8;i++)
  {
      sum=0;
   for(int j=0;j<=8;j++)
         sum+=storage[i][j];
   if(sum!=45) {cout<<"wrong"<<endl;   return 0;}
     }
 for( j=0;j<=8;j++)
  {
      sum=0;
   for(i=0;i<=8;i++)
         sum+=storage[i][j];
   if(sum!=45)  {cout<<"wrong"<<endl;   return 0;}
     }
 for(i=0;i<=8;i++)
 {
  sum=0;
  for(j=i/3*3;j<=i/3*3+2;j++)
   for(k=i%3*3;k<=i%3*3+2;k++)
    sum+=storage[j][k];
  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 main()
{
 int information_number=0;
 long time;
 char char_start[82];
    int int_start[82];
 ifstream cin_stream;
 cin_stream.open("d:\\c++\\数独12\\question\\fenlan.txt");
 cin_stream>>char_start;
 for(int i=0;i<=80;i++)
  int_start[i]=char_start[i]-'0';
 for(int i=0;i<=80;i++)
 {
  int row,col;
  if(int_start[i]!=0)
  {
  row=i/9;
  col=i%9;
  v1.push_back(row);
  v1.push_back(col);
  v1.push_back(int_start[i]);
  v2.push_back(v1);
  vstart.push_back(v1);
  vstart1.push_back(v1);
  v1.clear();
  }
 }
 information_number=v2.size();
 cin_stream.close();
 out_stream.open("d:\\c++\\数独12\\question\\question473.txt");
 time=clock(); 
 fills_up();
 for(int i=0;i<information_number;i++)
 {
  for(int k=0;k<=8;k++)
      semaphore[v2[i][0]][v2[i][1]][k]=0;
  probable[v2[i][0]][v2[i][1]]=0;
  storage[v2[i][0]][v2[i][1]]=v2[i][2];
 }
 print_all();//这里是输出题目,看看自己输入是否正确
 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();
 print_all();//这里是不用技巧时得到的解题结果
 if(finished==81)
  {
     print_all();
        out_stream<<endl;
     if(test()){ time=clock()-time;  out_stream<<"用时(不含输入数据时间)"<<time/1000<<"秒"<<time%1000<<"毫秒"<<endl;   cout<<"right"<<endl;}
     system("pause");
     return 0;
     }
 dfs();
 if(test())
 {
      print_all();
   out_stream<<endl;
      time=clock()-time;
      out_stream<<"用时(不含输入数据时间)"<<time/1000<<"秒"<<time%1000<<"毫秒"<<endl;
   cout<<"right"<<endl;
 }
    out_stream.close();
 system("pause");
 }

 

 

 

原创粉丝点击