離散數學(隱形唯一數)回溯(cpu_nc)30ms

QQ及郵箱:1 4 2 3 1 7 3 7 8 3 @qq.com 歡迎吹毛求疵。代碼混亂黏貼到vc2010就很工整。

本代碼摘自  數獨遊戲的解題算法——劉曉寶     《電腦編程技巧與維護》

#include<iostream>
#include<cstdlib>
#include<fstream>
#include<time.h>
#define N 9
using namespace std;

struct shudu
{   int ok;  int bit;};
int map[9][9]={
              8,0,0,0,0,0,0,0,0,
     0,0,3,6,0,0,0,0,0,
     0,7,0,0,9,0,2,0,0,
     0,5,0,0,0,7,0,0,0,
     0,0,0,0,4,5,7,0,0,
     0,0,0,1,0,0,0,3,0,
     0,0,1,0,0,0,0,6,8,
     0,0,8,5,0,0,0,1,0,
     0,9,0,0,0,0,4,0,0};


int num2bit(int);
int bit2num(int);
int bits(int);
int has_bit(int,int);
int isrow(int,int);
int iscol(int,int);
int shuduf(struct shudu sd_array[N][N],int sd_nine[3][N]);
bool test(struct shudu sd[N][N]);

 

int num2bit(int num)
{
 if(num<1) return(0);
 return(1<<(num-1));
}
int bit2num(int bit)
{
 int i,sum=0;
 for(i=1;i<=N;i++)
  if(has_bit(bit,num2bit(i)))    sum=sum*10+i;
 return(sum);
}
int bits(int bit)
{
 int i,sum=0;
 for(i=1;i<=N;i++)
  if(has_bit(bit,num2bit(i)))  sum++;
 return(sum);
}
int has_bit(int num,int bit)
{
 return(num & bit);
}
int isrow(int i,int j)
{
 return(i/3*3+j/3);
}
int iscol(int i,int j)
{
 return(i%3*3+j%3);
}
int shuduf(struct shudu sd_array[N][N],int sd_nine[3][N])
{
 int i,j,k,r,c,n,kok,temp_bit;
 struct shudu shudu_array[N][N];
 int shudu_nine[3][N];
 memcpy(shudu_array,sd_array,sizeof(struct shudu)*N*N);
 memcpy(shudu_nine,sd_nine,sizeof(int)*3*N);
 kok=1;
 while(kok==1)
 {
  kok=0;
  for(i=0;i<N;i++)
  {
   for(j=0;j<N;j++)
   {
    if(shudu_array[i][j].ok==0)
    {
     shudu_array[i][j].bit=(shudu_nine[0][i] | shudu_nine[1][j] | shudu_nine[2][isrow(i,j)])^(num2bit(N+1)-1);
     if(shudu_array[i][j].bit==0)   return(-1);//{ printf("\n第%d行,第%d列,爲0,有誤!\n",i+1,j+1);  return(-1);}
     if(bits(shudu_array[i][j].bit)==1)
     {
                       shudu_array[i][j].ok=1;  kok=1;
        shudu_nine[0][i]|=shudu_array[i][j].bit;
        shudu_nine[1][j]|=shudu_array[i][j].bit;
        shudu_nine[2][isrow(i,j)]|=shudu_array[i][j].bit;
     }
    }
    //printf("%9d|",bit2num(shudu_array[i][j].bit));
   }
   //printf("\n");
  }
  for(i=0;i<N;i++)
   for(j=0;j<N;j++)
   {
    r=c=n=0;
    for(k=0;k<N;k++)
     if(k!=j)
     {
      r|=shudu_array[i][k].bit;
      c|=shudu_array[k][i].bit;
      n|=shudu_array[isrow(i,j)][iscol(i,j)].bit;
     }
                r=shudu_array[i][j].bit & (r^shudu_array[i][j].bit);
    c=shudu_array[j][i].bit & (c^shudu_array[j][i].bit);
    n=shudu_array[isrow(i,j)][iscol(i,j)].bit & (n^shudu_array[isrow(i,j)][iscol(i,j)].bit);
    if(bits(r)==1 && shudu_array[i][j].ok==0)
    {
     if(has_bit(shudu_nine[0][i],r) || has_bit(shudu_nine[1][j],r) || has_bit(shudu_nine[2][isrow(i,j)],r) )
      return(-1);
     shudu_array[i][j].bit=r;
     shudu_array[i][j].ok=1;  kok=1;
     shudu_nine[0][i]|=shudu_array[i][j].bit;
     shudu_nine[1][j]|=shudu_array[i][j].bit;
     shudu_nine[2][isrow(i,j)]|=shudu_array[i][j].bit;
    }
    if(bits(c)==1 && shudu_array[j][i].ok==0)
    {
     if(has_bit(shudu_nine[0][j],c) || has_bit(shudu_nine[1][i],c) || has_bit(shudu_nine[2][isrow(j,i)],c) )
      return(-1);
     shudu_array[j][i].bit=c;
     shudu_array[j][i].ok=1;  kok=1;
     shudu_nine[0][j]|=shudu_array[j][i].bit;
     shudu_nine[1][i]|=shudu_array[j][i].bit;
     shudu_nine[2][isrow(j,i)]|=shudu_array[j][i].bit;
    }
    if(bits(n)==1 && shudu_array[isrow(i,j)][iscol(i,j)].ok==0)
    {
     if(has_bit(shudu_nine[0][isrow(i,j)],n) || has_bit(shudu_nine[1][iscol(i,j)],n) || has_bit(shudu_nine[2][i],n) )
      return(-1);
     shudu_array[isrow(i,j)][iscol(i,j)].bit=n;
     shudu_array[isrow(i,j)][iscol(i,j)].ok=1;  kok=1;
     shudu_nine[0][isrow(i,j)]|=shudu_array[isrow(i,j)][iscol(i,j)].bit;
     shudu_nine[1][iscol(i,j)]|=shudu_array[isrow(i,j)][iscol(i,j)].bit;
     shudu_nine[2][i]|=shudu_array[isrow(i,j)][iscol(i,j)].bit;
    }
   }
   //printf("=======================\n");
 }//while
 for(i=0;i<N;i++)  //檢查題目是否得到解
  if(shudu_nine[0][i]==(num2bit(N+1)-1) && shudu_nine[1][i]==(num2bit(N+1)-1) && shudu_nine[2][i]==(num2bit(N+1)-1))   kok++;
 if(kok==N && test(shudu_array))     return(1);
 for(i=0;i<N;i++)
  for(j=0;j<N;j++)
   if(shudu_array[i][j].ok==0)
   {
    for(k=1;k<=N;k++)
     if(has_bit(shudu_array[i][j].bit,num2bit(k)))
     {
      temp_bit=shudu_array[i][j].bit;
      shudu_nine[0][i]|=num2bit(k);
      shudu_nine[1][j]|=num2bit(k);
      shudu_nine[2][isrow(i,j)]|=num2bit(k);
      shudu_array[i][j].ok=1;
      shudu_array[i][j].bit=num2bit(k);
      //printf("=======================\n");
      //printf("嘗試:第%d行,第%d列,%d中的%d\n",i+1,j+1,bit2num(temp_bit),k);
      if(shuduf(shudu_array,shudu_nine)==1)    return(1);
      shudu_array[i][j].bit=temp_bit & (num2bit(k)^(num2bit(N+1)-1));
      shudu_array[i][j].ok=0;
      shudu_nine[0][i] &=(num2bit(k)^(num2bit(N+1)-1));
      shudu_nine[1][j] &=(num2bit(k)^(num2bit(N+1)-1));
      shudu_nine[2][isrow(i,j)] &=(num2bit(k)^(num2bit(N+1)-1));
     }
                if(shudu_array[i][j].bit==0)   return(-2);  //無解
   }
     return(1);
}//shuduf
bool test(struct shudu sd[N][N])
{
 int i,j;
 for(i=0;i<N;i++)
  for(j=0;j<N;j++)
   if(sd[i][j].ok!=1 ||  bits(sd[i][j].bit)!=1)  return(false);
 return(true);
}

 

int main()
{
   int i,j,rc;
   struct shudu shudu_array[N][N];
   int shudu_nine[3][N];
   long start,finish;
   memset(shudu_nine,0,sizeof(int)*3*N);
   start=clock();
   freopen("d:\\c++\\數獨12\\question\\question475.txt","w",stdout);
   for(i=0;i<N;i++)
    for(j=0;j<N;j++)
    {
     if(map[i][j]>0)
     {
      shudu_array[i][j].bit=num2bit(map[i][j]);
      shudu_array[i][j].ok=1;
     }
     else
     {
      shudu_array[i][j].bit=0;
      shudu_array[i][j].ok=0;
     }
     if(has_bit(shudu_nine[0][i],shudu_array[i][j].bit) || has_bit(shudu_nine[1][j],shudu_array[i][j].bit) || has_bit(shudu_nine[2][isrow(i,j)],shudu_array[i][j].bit) )
     {  printf("輸入有誤\n");  return(-1); }
     shudu_nine[0][i]|=shudu_array[i][j].bit;
     shudu_nine[1][j]|=shudu_array[i][j].bit;
     shudu_nine[2][isrow(i,j)]|=shudu_array[i][j].bit;
    }
    ;
   rc=shuduf(shudu_array,shudu_nine);
   if(rc==1)  printf("有解\n");
   else if(rc==-2)   printf("無解\n");
   finish=clock();
   cout<<finish-start<<"毫秒"<<endl;
   fclose(stdout);
}

 

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