ccy测试dlx 模块化与全局变量

来源:互联网 发布:网络授权申请书 编辑:程序博客网 时间:2024/06/03 13:39

http://blog.sina.com.cn/s/blog_51cea4040100gxn1.html   下面内容是此链接的作者发给我的,可能是ccy自己写的也可能是她的朋友写的。

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

//测试预计14h (同方预测)  11-20  13:20--------
//这一版测试忘了把测试不通过的题目和结果打印出来,考虑到最近的测试都通过了,姑且把。
//实际耗时约12.41h (同方测试)
#include <iostream>
#include<time.h>
#include<cstdlib>
#include<fstream>
using namespace std;

#define BLANKS   55
#define FAIL     20
int table[9][9],table_for_solve[9][9],solves=0,op;
fstream out_stream;

#define NN 3
#define N (NN*NN)
#define MAXN (N*N*N+1)
#define MAXM ((N*N)*4+1)

struct type
{
 int l,r,u,d,x,y;
} po[MAXN*MAXM];

int a[MAXN][MAXM],n,m,tot,c[MAXM],all;
int pn[MAXN][2],pm[MAXM][2],ans;
int sc[N*N];


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]);


void get(int,int,int);
void make(int,int);
int score(int);
void pre();
void remove(int);
void resume(int);
bool dfs(int);
void print();
int test();
bool  fun( int a[10]);


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

 

void get(int x,int y,int z)
{
 int o=x*N*N+y*N+z,w=x/NN*NN+y/NN;
 a[o][x*N+z]=1;
 a[o][N*N+y*N+z]=1;
 a[o][N*N*2+w*N+z]=1;
 a[o][N*N*3+x*N+y+1]=1;
}
void make(int x,int y)
{
 po[tot].x=x;
 po[tot].y=y;
 c[y]++;
 if (pn[x][0]<0)
  pn[x][0]=tot;
 else
 {
  po[tot].l=pn[x][1];
  po[pn[x][1]].r=tot; 
 }
 pn[x][1]=tot;
 po[pn[x][0]].l=tot;
 po[tot].r=pn[x][0];
 if (pm[y][0]<0)
  pm[y][0]=tot;
 else
 {
  po[tot].u=pm[y][1];
  po[pm[y][1]].d=tot; 
 }
 pm[y][1]=tot;
 po[pm[y][0]].u=tot;
 po[tot].d=pm[y][0];
 tot++;
}
int score(int w)
{
 int x=w/9,y=w%9;
 if (x==0||x==8||y==0||y==8)
  return 6;
 if (x==1||x==7||y==1||y==7)
  return 7;
 if (x==2||x==6||y==2||y==6)
  return 8;
 if (x==4&&y==4)
  return 10;
 return 9;
}
void pre()
{
 int i,j,k,x;
 memset(po,-1,sizeof(po));
 memset(pn,-1,sizeof(pn));
 memset(pm,-1,sizeof(pm));
 memset(a,0,sizeof(a));
 memset(c,0,sizeof(c));
 n=MAXN-1;
 m=MAXM-1;
 all=0;
 for (i=0;i<N*N;i++)
 {
  sc[i]=score(i);
  all+=sc[i]*10;
 }
 ans=all;
 for (i=0;i<=m;i++)
  a[0][i]=1;
 for (i=0;i<N;i++)
  for (j=0;j<N;j++)
  {
   //scanf("%d",&x);
   if (table[i][j]==0)
    for (k=1;k<=N;k++)
     get(i,j,k);
   else
    get(i,j,table[i][j]);
  }
 tot=0;
 for (i=0;i<=n;i++)
  for (j=0;j<=m;j++)
   if (a[i][j])
    make(i,j);
 for(int i=0;i<=m;i++)
  c[i]--;
}
void remove(int k)
{
 int i,j;
 po[po[k].l].r=po[k].r;
 po[po[k].r].l=po[k].l;
 for (i=po[k].d;i!=k;i=po[i].d)
  for (j=po[i].r;j!=i;j=po[j].r)
  {
   po[po[j].u].d=po[j].d;
   po[po[j].d].u=po[j].u;
   c[po[j].y]--;
  }
}
void resume(int k)
{
 int i,j;
 for (i=po[k].u;i!=k;i=po[i].u)
  for (j=po[i].l;j!=i;j=po[j].l)
  {
   c[po[j].y]++;
   po[po[j].u].d=j;
   po[po[j].d].u=j;  
  }
 po[po[k].l].r=k;
 po[po[k].r].l=k;
}
bool dfs(int now)
{
 int x=n+2,o,i,j,z;
 if (po[0].r==0)
 {
  ans=now;
  return(true);
 }
 for (i=po[0].r;i!=0;i=po[i].r)
  if (c[po[i].y]<x)
   x=c[po[o=i].y];
 remove(o);
 for (i=po[o].d;i!=o;i=po[i].d)
 {
  for(j=po[i].r;j!=i;j=po[j].r)
   remove(po[j].y);
  z=sc[(po[i].x-1)/N]*((po[i].x-1)%N+1);
  table[(po[i].x-1)/N/N][(po[i].x-1)/N%N]=(po[i].x-1)%N+1;
  if (z+now<ans)
   if(dfs(z+now))  return(true);
  for(j=po[i].l;j!=i;j=po[j].l)
   resume(po[j].y);
 }
 resume(o);
 return(false);
}
void print()
{
 for(int i=0;i<N;i++)
 {
  if(i%3==0) out_stream<<endl;//printf("\n");
  for(int j=0;j<N;j++)
   if(j%3==0) out_stream<<" "<<table[i][j]<<" ";//printf(" %d ",table[i][j]);
   else       out_stream<<table[i][j]<<" ";//printf("%d ",table[i][j]);
        out_stream<<endl;//printf("\n");
 }
 out_stream<<endl;
}
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+=table[i-1][j-1];  aray[j]=table[i-1][j-1];}
   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+=table[i-1][j-1];  aray[i]=table[i-1][j-1];}
   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+=table[i-1][j-1];  aray[sub++]=table[i-1][j-1];}
        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);
}


int main()
{
 out_stream.open("d:\\c++\\数独12\\question\\question472.txt");
 srand(time(0));
 long time1,time2;
 time1=clock();
    while (op<=1000000)
    {
        if (op==1000001) break;
  create_gameover();
        while(!create_game(BLANKS))
          create_gameover();
     pre();
     dfs(0);
     if (ans<all && test())   ;//print();
     //printf("%d,%d\n",all,ans);
     else
     out_stream<<"第"<<op<<"题测试不通过"<<endl;//printf("第%d题No answer!",op);
  op++;
    }
 time2=clock();
 out_stream<<time2-time1<<"ms"<<endl;
 out_stream.close();
}

 

原创粉丝点击