求助:两个代码调试遇到一类问题 :有未经处理的异常: 0xC0000005: Access violation

下面这个代码是生成一个数独题目(58空格),有时能生产,有时则出现错误。

#include <iostream>
#include <cstdlib>
#include <ctime>
#include<time.h>
#include<fstream>
#define BLANKS   58
#define FAIL     50
using namespace std;
int table[9][9],solves=0,nothing[162+1],n_sub=1;
fstream out_stream;


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);
bool test();
void print_all();
void dfs();
int check(int y,int x,int *mark) ; //求probable[y][x]  并且mark[]中为0的元素说明可以试探
int solve();
bool create_game(int blanks);
void print_all(int k);  //输出到文件


void shuffle(int arr[], int n)
{
         int tmp, rd;
        for(int i = 0; i < n; i++)
            {
                rd = rand() % 9;
                tmp = arr[rd];
               arr[rd] = arr[i];
               arr[i] = tmp;
          }
}
bool test(int x, int y, int v)
{
        int _x = x / 3 * 3;
        int _y = y / 3 * 3;
       for(int i = _x; i < _x + 3; i++)                  //测试3 * 3矩阵内是否有重复的数
         {
            for(int j = _y; j < _y + 3; j++)
              {
                   if(table[i][j] == v)
                      {
                         return false;
                      }
              }
        }
     for(int i = 0; i < 9; i++)                       //测试横向、纵向是否有重复的数
        {
            if(table[x][i] == v || table[i][y] == v)
                 return false;
       }
    return true;
}
bool put(int line, int index)
{
       if(index > 8)
            return true;
       int num[] = {1,2,3,4,5,6,7,8,9};
                                                  //打乱当前准备写入数字的前后顺序
       shuffle(num, 9);
       for(int i = 0; i < 9; i++)
                                                       //测试数字是否允许填入当前方格
          if( test(line, index, num[i]) == true )
             {
                table[line][index] = num[i];
                                                       //填入成功则处理下一个方格
                 if( put(line, index + 1) == true )
                    {
                        return true;
                    }
           }
      table[line][index] = 0;                           //失败后复位
     return false;
}
bool put_line(int line)
{
         if(line > 8)
             return true;
         if( put(line, 0) == true )
                                                               //当前一行添入完成后,进入下一行再重复处理。
              if( put_line(line + 1) == true )
                    return true;
        for(int i = 0; i < 9; i++)
                 table[line][i] = 0;
        return false;
}
void print_all()

          cout<<"print storage"<<endl;
          for(int i=1;i<=9;i++)
            {
                for(int j=1;j<=9;j++)
                    {
                         cout<<table[i-1][j-1]<<" ";
                          if(j%3==0) cout<<"   ";
                    }   
                cout<<endl;
                if(i%3==0)  cout<<endl;
            }
         cout<<endl<<endl;
}
void dfs()
{
         int i,j,im=-1,jm,min=10;
         int mark[10];
         for(i=0;i<9;++i)
                 for(j=0;j<9;++j)
                    {
                       if(table[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[im][jm]=i;
                           dfs();
                       }
             table[im][jm]=0;
}
int solve()
{
          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[y][i]]=1;
          for(i=0;i<9;++i)
                mark[table[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[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=100,col,tmp;
         srand(time(0));
         for( i=1;i<=blanks;i++)
             {
                 if(i==58)
                     system("pause");
                 int num=0;
                 do
                       {
                            if(row!=100)
                                  if(table[row][col]!=0)  
                                       {
                                           nothing[n_sub-1]=nothing[n_sub-2]=0;
                                           for(int j=1;j<=(n_sub-3)/2;j++)
                                           table[nothing[2*j-1]][nothing[2*j]]=0;
                                          n_sub-=2;
                                       }
                          do
                                {
                                       k=rand()%81;
                                       row=k/9 ;
                                       col=k-9*row;
                                       tmp=table[row][col];
                               }while(tmp==0);
                          table[row][col]=0;
                          nothing[n_sub++]=row; nothing[n_sub++]=col;
                          num++;
                          if(num==FAIL)  
                                {
                                     for(int i=0;i<=n_sub-1;i++)
                                            nothing[i]=0;
                                      return(false);
                                 }
                       }while((solve()==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;
          srand((unsigned int)time(NULL));
          shuffle(table[0], 9);
                                                        //从第二行开始添入数字
          while(!put_line(1))   ;
}
void print_all(int k)

         for(int i=1;i<=9;i++)
            {
                for(int j=1;j<=9;j++)
                   {
                        out_stream<<table[i-1][j-1]<<" ";
                        if(j%3==0) out_stream<<"   ";
                   }   
                out_stream<<endl;
                if(i%3==0)  out_stream<<endl;
            }
         out_stream<<endl<<endl;
}

int main()
{
          long time1=clock();
          create_gameover();
          while(!create_game(BLANKS))
          create_gameover();
          print_all();
          out_stream.open("d:\\c++\\数独12\\question\\生成题2.txt");
          print_all(1);
          out_stream.close();
          time1=clock()-time1;
          cout<<"use time "<<time1/1000<<"s"<<time1%1000<<"ms"<<endl;
          system("pause");
}

 

 

下面这个代码是生产一个16*16终盘,有时正确,有时错误,错误同样是有未经处理异常,访问冲突。

#include<cstdlib>
#include<time.h>
#include<iostream>
using namespace std;
int count=0,vessel[362880][16];
int b[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},m=0;
int data[16][16],data1[16][16];
int line[16][16], column[16][16], block[16][16];
int Initial(int i, int j, int start);
void shuffle(int arr[]);
void move1(int list[],int a,int b);
void move2(int list[],int a,int b);
void Perm(int list[], int s, int e) ;                   

void move1(int list[],int a,int b)
{
      int tmp=*(list+b);
      for(int i=b-1;i>=a;i--)
           *(list+i+1)=*(list+i);
      *(list+a)=tmp;
}
void move2(int list[],int a,int b)
{
       int tmp=*(list+a);
       for(int i=a+1;i<=b;i++)
             *(list+i-1)=*(list+i);
      *(list+b)=tmp;
}
void Perm(int list[], int s, int e)                     //对list[k]——list[m]进行全排列(可以有重复元素)
{                                                       //这里可以改动成对k到m的奇数(偶数引申到给出一个公式即一种顺序)下标进行排列  
        if(s>e)
           {
                  for(int k=0;k<=15;k++)
                 vessel[count][k]=list[k];
                 count++;
                 if(count==362880)  return;
           }
       for (int i=s; i <= e; i++)
           {
               move1(list,s,i);
               Perm(list,s+1,e);
               if(count==362880)  return;
               move2(list,s,i);
          }
}
void shuffle(int arr[])
{
         int tmp, rd;
         for(int i = 0; i <=15 ; i++)
             {
                   rd = rand() % 16;
                  tmp = arr[rd];
                  arr[rd] = arr[i];
                  arr[i] = tmp;
             }
}
int Initial(int i, int j, int start)
{
        //if(i==8)
        //system("pause");
        int k;
        for (k = start;k>=0;k--)        //从1至9依次试验
          {
              if (!line[i][b[k]-1] && !column[j][b[k]-1] && !block[i/4*4+j/4][b[k]-1])
                   {
                        data[i][j] = b[k];
                        data1[i][j]=k;
                        line[i][b[k]-1] = 1;
                        column[j][b[k]-1] = 1;
                        block[i/4*4+j/4][b[k]-1] = 1;

                        if (i == 15 && j == 15)        //初始化完毕退出
                            {
                                 return(1);
                            }

                       if (j == 15)                    //定位下一位置                   
                           {
                               j = 0;
                               i++;
                               if(i==4)
                                  {
                                      int mm=rand()%362880;
                                      for(int j=0;j<=15;j++)
                                      b[j]=vessel[mm][j];
                                  }
                               if(i==8)
                                 {
                                       int mm=rand()%362880;
                                       for(int j=0;j<=15;j++)
                                       b[j]=vessel[mm][j];
                                 }
                              if(i==12)
                                 {
                                      int mm=rand()%362880;
                                      for(int j=0;j<=15;j++)
                                     b[j]=vessel[mm][j];
                                 }
                      }
                 else
                         j++;
                  Initial(i, j, 15);            //初始化下一位置
                 return 1;
          }
       
        if (k == 0)                        //1至9均无合适值,回溯
        {
            do
            {
                if (j == 0)                //定位前一位置
                {
                    j = 15;
                    i--;
                }
                else
                    j--;
                line[i][data[i][j]-1] = 0;
                column[j][data[i][j]-1] = 0;
                block[i/4*4+j/4][data[i][j]-1] = 0;
            }while (data[i][j] == b[0]);

            //回溯到一可以继续的位置,从这一位置开始递归赋值
            Initial(i, j, data1[i][j] -1);
            return 1;                    //递归结束返回后立即退出
        }
    }//for
}

int main()
{
        int i, j;
         long time1;
         time1=clock();
         Perm(b,0,15);
        srand(time(0));
        for(int u=1;u<=100;u++)
            {
               shuffle(b);
               Initial(0,0,15);
                for(int i=0;i<=15;i++)
               for(int j=0;j<=15;j++)
                 {
                      data[i][j]=0;
                      data1[i][j]=0;
                       line[i][j]=0;
                      column[i][j]=0;
                      block[i][j]=0;
                }
          }
      printf("%ums\n",clock()-time1);
      for (i = 0; i < 16; i++)           
      {
           for (j = 0; j < 16; j++)
               printf("%i ", data[i][j]);
           printf("\n");
      }
    system("pause");
}


 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值