求助:生成一个16*16数独终盘

QQ:1423173783    邮箱:1423173783@qq.com

我想在一秒内生成一个16*16数独的终盘。(终盘就是16*16都填满了,又符合每行每列每宫包含1,2,...16这些数) 当然是随机生成,如果构造一个我1ms就能造一个,还能造一堆。就是说随机生成一个终盘(这里不作严格要求:生成的那一个终盘是理论上有可能的任一个)。不需要如此严格的要求。只要1m内能生成一个随机的16*16终盘,而这个终盘的题库又大到专家不可能推出来)。实际上你可以完全构造一个16*16终盘,让后做一个映射1,2,...16变成16,15,...1,这里举得映射只是16!的一种。换句话说你构造一个终盘就等于构造了16!个不同的形式不一实质一样的终盘,这只是做了个映射,其实还可以做很多变换,变成形式不一本质一样的终盘。我要的不是这样的东西。我要的是1m内确实能从本质不一样的海量理论可能中生成一个终盘就行。

我用一个算法生成9*9终盘,1ms一个,可是做16*16一个小时也生成不了一个。我的算法生成的一个终盘是形式上,本质上理论上所有可能中随机生成一个,如果是开发游戏,这个题库就相当大了。大到什么程度我给你大约算下。以9*9为例:假如我们构造一个终盘,先在第一行确定1所在位置,然后在第二行确定2所在位置,一次类推最后在第九行确定9所在位置,至此确定了九个数的位置。算下有多少种可能,9的9次方,大约3亿。我只确定了9个数的位置还有72个位置没填数,你想想最后的终盘可能数是多少。
#include <iostream>
#include <cstdlib>
#include <ctime>
#include<time.h>
#include<cstdlib>
#define  K   4
using namespace std;
int table[K*K][K*K];
void shuffle(int arr[])
{
    int tmp, rd;
    for(int i = 0; i < K*K; i++)
 {
        rd = rand() % (K*K);
        tmp = arr[rd];
        arr[rd] = arr[i];
        arr[i] = tmp;
    }
}
bool test(int x, int y, int v)
{
   
    int _x = x / K * K;
    int _y = y / K * K;
 //测试3 * 3矩阵内是否有重复的数
    for(int i = _x; i <=x-1; i++)
        for(int j = _y; j <= _y + K-1; j++)
            if(table[i][j] == v)   return false;
    //测试横向、纵向是否有重复的数
    for(int j = 0; j <=y-1; j++)
        if(table[x][j] == v )      return false;
    for(int i=0;i<=x-1;i++)
  if(table[i][y]==v) return (false);
    return true;
}
int main()
{
    long time1=clock();
 int b[K*K];
 for(int i=0;i<=K*K-1;i++)
  b[i]=i+1;
 //int num=0;
 //do
 //{
 for(int i=0;i<=K*K-1;i++)
  table[0][i]=i+1;
    srand((unsigned int)time(NULL));
    shuffle(table[0]);
    for (int x=1;x<=K*K-1;x++)
     {
    for (int y=0;y<=K*K-1;y++)
        {
             int i;
    shuffle(b);
             for( i=0;i<=K*K-1;i++)
    {
                 if(test(x,y,b[i]))
     { table[x][y]=b[i];  break;}
    }
            if(i==K*K && y>0)
   {
    for(int m=0;m<=y-1;m++)
         table[x][m]=0;
    y=-1;
    if(x>=2)
    {
     for(int i=0;i<=K*K-1;i++)
      table[x-1][i]=0;
     x-=2;
     break;
    }
   }
   else if(i==K*K && y==0)
   {
    for(int i=0;i<=K*K-1;i++)
     table[x-1][i]=0;
    x-=2;
    break;
   }
       }
    }
 /*for(int i=0;i<=8;i++)
  for(int j=0;j<=8;j++)
   table[i][j]=0;*/
 //num++;
 //}while(num<1000);
    for(int x=0;x<=K*K-1;x++)
 {
        for(int y = 0; y <=K*K-1; y++)
            cout << table[x][y] << " ";
        cout << endl;
    }
 time1=clock()-time1;
 cout<<"use time "<<time1/1000<<"s"<<time1%1000<<"ms"<<endl;
    system("pause");
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值