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");
}
#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");
}