QQ:1423173783 邮箱:1423173783@qq.com
文章最后有总结。和展望。
#include<cstdlib>
#include<time.h>
#include<iostream>
using namespace std;
int count=0,vessel[362880][9];
int b[9]={1,2,3,4,5,6,7,8,9},m=0;
int data[9][9],data1[9][9],data_vessel[362880][6][9];
int line[9][9], column[9][9], block[9][9];
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)
{
if(s>e)
{
for(int k=0;k<=8;k++)
vessel[count][k]=list[k];
count++;
}
for (int i=s; i <= e; i++)
{
move1(list,s,i);
Perm(list,s+1,e);
move2(list,s,i);
}
}
void shuffle(int arr[])
{
int tmp, rd;
for(int i = 0; i <=8 ; i++)
{
rd = rand() % 9;
tmp = arr[rd];
arr[rd] = arr[i];
arr[i] = tmp;
}
}
int Initial(int i, int j, int start)
{
int k;
for (k = start;k>=0;k--)
{
if (!line[i][b[k]-1] && !column[j][b[k]-1] && !block[i/3*3+j/3][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/3*3+j/3][b[k]-1] = 1;
if (i == 5 && j == 8)
{
for(int i=0;i<=5;i++)
for(int j=0;j<=8;j++)
{
data_vessel[m][i][j]=data[i][j];
line[i][data[i][j]-1]=0;
column[j][data[i][j]-1]=0;
block[i/3*3+j/3][data[i][j]-1]=0;
data[i][j]=0;
}
return(1);
}
if (j == 8)
{
j = 0;
i++;
if(i==3)
for(int j=0;j<=8;j++)
b[j]=vessel[m][j];
}
else
j++;
Initial(i, j, 8);
return 1;
}
if (k == 0)
{
do
{
if (j == 0)
{
j = 8;
i--;
}
else
j--;
line[i][data[i][j]-1] = 0;
column[j][data[i][j]-1] = 0;
block[i/3*3+j/3][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,8);
for( m=0;m<=362879;m++)
{
for(int i=0;i<=8;i++)
b[i]=i+1;
Initial(0,0,8);
}
for(int i=0;i<=362878;i++)
{
if(data_vessel[i][0][0]==0) continue;
for(int j=i+1;j<=362879;j++)
{
int m;
for(m=0;m<=5;m++)
for(int n=0;n<=8;n++)
if(data_vessel[i][m][n]!=data_vessel[j][m][n])
goto temp;
if(m==6) data_vessel[j][0][0]=0;
temp: ;
}
}
int num=0;
for(int i=0;i<=362879;i++)
if(data_vessel[i][0][0]!=0) num++;
cout<<num<<endl;
printf("%ums\n",clock()-time1);
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
printf("%i ", data_vessel[16634][i][j]);
printf("\n");
}
system("pause");
}
#include<cstdlib>
#include<time.h>
#include<iostream>
using namespace std;
int count=0,vessel[362880][9];
int b[9]={1,2,3,4,5,6,7,8,9},m=0;
int data_vessel[362880][1][9];
int data[9][9]={ 1,2,3,4,5,6,7,8,9,
4,5,6,7,8,9,1,2,3,
7,8,9,1,2,3,4,5,6,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0};
int line[9][9]={ 1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0};
int block[9][9]={ 1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0};
int column[9][9]={ 1,0,0,1,0,0,1,0,0,
0,1,0,0,1,0,0,1,0,
0,0,1,0,0,1,0,0,1,
1,0,0,1,0,0,1,0,0,
0,1,0,0,1,0,0,1,0,
0,0,1,0,0,1,0,0,1,
1,0,0,1,0,0,1,0,0,
0,1,0,0,1,0,0,1,0,
0,0,1,0,0,1,0,0,1};
void Initial(int i, int j, int start);
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)
{
if(s>e)
{
for(int k=0;k<=8;k++)
vessel[count][k]=list[k];
count++;
}
for (int i=s; i <= e; i++)
{
move1(list,s,i);
Perm(list,s+1,e);
move2(list,s,i);
}
}
void Initial(int i, int j, int start)
{
int k;
for (k = start;k>=0;k--) //从1至9依次试验
{
if (!line[i][k] && !column[j][k] && !block[i/3*3+j/3][k])
{
data[i][j] = k+1;
line[i][k] = 1;
column[j][k] = 1;
block[i/3*3+j/3][k] = 1;
if (i == 3 && j == 8) //初始化完毕退出
{
for(int j=0;j<=8;j++)
data_vessel[m][i-3][j]=data[i][j];
m++;
line[i][data[i][j]-1]=0;
column[j][data[i][j]-1]=0;
block[i/3*3+j/3][data[i][j]-1]=0;
data[i][j]=0;
break;
}
Initial(i, j+1, 8);
line[i][data[i][j]-1]=0;
column[j][data[i][j]-1]=0;
block[i/3*3+j/3][data[i][j]-1]=0;
data[i][j]=0;
}
}//for
}
int main()
{
int i, j;
long time1;
time1=clock();
Perm(b,0,8);
Initial(3,0,8);
printf("%u\n",m);
printf("%ums\n",clock()-time1);
system("pause");
}
#include<cstdlib>
#include<time.h>
#include<iostream>
using namespace std;
int count=0,vessel[362880][9];
int b[9]={1,2,3,4,5,6,7,8,9},m=0;
int data1[9][9],data_vessel[362880][3][9];
int data[9][9]={ 9,8,7,6,5,4,3,2,1,
6,5,4,3,2,1,9,8,7,
3,2,1,9,8,7,6,5,4,
8,9,6,7,4,5,2,1,3,
7,4,5,2,1,3,8,9,6,
2,1,3,8,9,6,7,4,5,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0};
int line[9][9]= { 1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0};
int block[9][9]= { 1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0};
int column[9][9]= { 0,1,1,0,0,1,1,1,1,
1,1,0,1,1,0,0,1,1,
1,0,1,1,1,1,1,0,0,
0,1,1,0,0,1,1,1,1,
1,1,0,1,1,0,0,1,1,
1,0,1,1,1,1,1,0,0,
0,1,1,0,0,1,1,1,1,
1,1,0,1,1,0,0,1,1,
1,0,1,1,1,1,1,0,0};
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) ; //对list[s]——list[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)
{
if(s>e)
{
for(int k=0;k<=8;k++)
vessel[count][k]=list[k];
count++;
}
for (int i=s; i <= e; i++)
{
move1(list,s,i);
Perm(list,s+1,e);
move2(list,s,i);
}
}
void shuffle(int arr[])
{
int tmp, rd;
for(int i = 0; i <=8 ; i++)
{
rd = rand() % 9;
tmp = arr[rd];
arr[rd] = arr[i];
arr[i] = tmp;
}
}
int Initial(int i, int j, int start)
{
int k;
for (k = start;k>=0;k--)
{
if (!line[i][b[k]-1] && !column[j][b[k]-1] && !block[i/3*3+j/3][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/3*3+j/3][b[k]-1] = 1;
if (i == 8 && j == 8)
{
for(int i=6;i<=8;i++)
for(int j=0;j<=8;j++)
{
data_vessel[m][i-6][j]=data[i][j];
line[i][data[i][j]-1]=0;
column[j][data[i][j]-1]=0;
block[i/3*3+j/3][data[i][j]-1]=0;
data[i][j]=0;
}
return(1);
}
if (j == 8)
{
j = 0;
i++;
}
else
j++;
Initial(i, j, 8);
return 1;
}
if (k == 0)
{
do
{
if (j == 0)
{
j = 8;
i--;
}
else
j--;
line[i][data[i][j]-1] = 0;
column[j][data[i][j]-1] = 0;
block[i/3*3+j/3][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,8);
for( m=0;m<=362879;m++)
{
for(int i=0;i<=8;i++)
b[i]=vessel[m][i];
Initial(6,0,8);
}
for(int i=0;i<=362878;i++)
{
if(data_vessel[i][0][0]==0) continue;
for(int j=i+1;j<=362879;j++)
{
int m;
for(m=0;m<=2;m++)
for(int n=0;n<=8;n++)
if(data_vessel[i][m][n]!=data_vessel[j][m][n])
goto temp;
if(m==3) data_vessel[j][0][0]=0;
temp: ;
}
}
int num=0;
for(int i=0;i<=362879;i++)
if(data_vessel[i][0][0]!=0) num++;
cout<<num<<endl;
printf("%ums\n",clock()-time1);
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
printf("%i ", data_vessel[16634][i][j]);
printf("\n");
}
system("pause");
}
这篇文章得到的结论:用这篇文章的算法(每个代码本质上一样,为了不同的目的做了写修改)能生成一些有规律的终盘:
这里指的一些到底有多少: 分两种情况:形式不一的终盘可以生成 9!*12096*216=948109639680 约9481亿个
本质不一的终盘可以生成 12096*216=2612736 约261万个
算法中每天横带产生一个种子。每选一个种子都有9!可能,当然这么多可能肯定会产生重复的终盘,上面的计算是剔除重复的情况。
这种算法生成的终盘量是很大的,但都有共同的规律,如果解题人解出题后发现了这个规律,能否推出三个种子我打文字时第一次开始考虑这个问题。第一个种子是
不用推导,第二个种子和第三个种子如何推导,如果推导不了,能否写个算法全部打印到文件?
还有个问题我之前就思考过,如果每填一行给个种子,或每两行给个种子,终盘的生成数又如何算,显然能生成的终盘更多。