问一下 16皇后的解法有几种,我的计算机CUP 不够好,计算了好几小时好像算出了有 30多万种,还没算完。求解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了问一下 16皇后的解法有几种,我的计算机CUP 不够好,计算了好几小时好像算出了有 30多万种,还没算完。求解相关的知识,希望对你有一定的参考价值。

我在计算8皇后的时候得到的是92种,是正确的,不知道是否是代码的问题,就想的到正确的解法。

用C语言解8皇后问题  “残卷法”思想
设置一个三维数组,第一个下标是皇后的行坐标,第二个下标是皇后的列坐标,第三个下标是残卷号。相当于有N张叠在一起的8*8棋盘,每张棋盘只在复制前面棋盘及皇后后加放置一个皇后。直到放满8皇后后才是一张完整的8皇后图,称完卷。

这里实际操作时多加一行多加一列即第0行第0列,但这一行/列不作输出,只是作此行/列有无皇后的参考。

代码  #include
"stdio.h"

void main()

static int a[9][10][1645],x,y,i,j,z=1,k,flag,h,m,n=0;

for(k=1;k<=z;k++)

for(x=1;x<=8;x++)

if(x==8 && m==0)
flag=z+1;m=1;//残卷算到了第8行,表明已经是完卷。即完卷从l号残卷开始的。

if(a[x][0][k]==2) continue;//参考行等于2则表明此行己有皇后,下一行

for(y=1;y<=8;y++)

if(a[0][y][k]==2) continue;//参考列等于2则表明此列己有皇后,下一列

if(x>1) if(a[x-1][y-1][k]==1||a[x-1][y+1][k]==1)
continue;//左右对角线有皇后,下一列

if(x>2) if(a[x-2][y-2][k]==1||a[x-2][y+2][k]==1)
continue;

if(x>3) if(a[x-3][y-3][k]==1||a[x-3][y+3][k]==1)
continue;

if(x>4) if(a[x-4][y-4][k]==1||a[x-4][y+4][k]==1)
continue;

if(x>5) if(a[x-5][y-5][k]==1||a[x-5][y+5][k]==1)
continue;

if(x>6) if(a[x-6][y-6][k]==1||a[x-6][y+6][k]==1)
continue;

if(x>7) if(a[x-7][y-7][k]==1||a[x-7][y+7][k]==1)
continue;

for(i=0;i<9;i++)

for(j=0;j<9;j++)

a[i][j][z+1]=a[i][j][k];//复制当前残卷内容

a[x][y][z+1]=1;//放置一个皇后到新残卷

a[0][y][z+1]=2;//设置参考列为2,表明此列有皇后

a[x][0][z+1]=2;//设置参考行为2,表明此行有皇后

z++;//取下一个残卷号



break; 

for(k=flag;k<=z;k++)

//输出8皇后

for(i=1;i<=8;i++)

for(j=1;j<=8;j++)

printf("%d ",a[i][j][k]);

printf(" ");

for(j=1;j<=8;j++)

printf("%d ",a[9-j][i][k]);//将上图顺时针旋转90度得到新图

printf(" ");

for(j=1;j<=8;j++)

printf("%d ",a[9-i][9-j][k]);//将上图顺时针旋转90度得到新图

printf(" ");

for(j=1;j<=8;j++)

printf("%d ",a[j][9-i][k]);//将上图顺时针旋转90度得到新图

printf(" ");

printf("\n");



printf("\n");

n++;if(n%4==0) getchar();



printf("总共%d种 Hyber-bin制作",n*4);//输出总共有多少种


92种追问

嗯,你的方法不错,我想问的问题是,16皇后有几种解法,我想知道我的算法有没有错误!

追答

92种

追问

额 ,我想知道的是16皇后的解法个数,我已经知道8皇后的解法是有92种的。既然如此,你的 8皇后变成16皇后时,计算出来了正确的总数了吗? 计算的时间 应该会非常长吧。
不过 还是谢谢了

追答

你试下这段代码,因为到13皇后时用一般方法就是天量计算了。所以才会那么慢,这个应该快些
/*
ID: cmykrgb1
PROG: checker
LANG: C++
*/#include FILE*fi,*fo;unsignedlongint upperlim,sum;int a[14],n;

int ps(int a)//不用 log 节省时间switch(a)case1:return1;case2:return2;case4:return3;case8:return4;case16:return5;case32:return6;case64:return7;case128:return8;case256:return9;case512:return10;case1024:return11;case2048:return12;case4096:return13;

void test(unsignedlongint row,unsignedlongint ld,unsignedlongint rd,int deep)unsignedlongint pos,p;if(row!=upperlim)
pos=upperlim & ~(row | ld | rd);while(pos!=0)
p=pos &-pos;
pos=pos-p;if(sum>1,deep+1);else
sum++;int i;if(sum<=3)for(i=1;i<=n-1;i++)fprintf(fo,"%d ",ps(a[i]));fprintf(fo,"%dn",ps(a[n]));



int main(void)
fi=fopen("checker.in","r");
fo=fopen("checker.out","w");fscanf(fi,"%d",&n);fclose(fi);
upperlim=(1<< n)-1;
test(0,0,0,1);fprintf(fo,"%dn",sum);fclose(fo);return0;

参考技术A 目测上千万,稍等啊,我给你算算,嘿嘿 ,共14772512。要注意你的算法效率,cpu再强大也顶不住啊~

同步和异步

你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下”,然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。

而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。

你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果。

如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。

在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。

 

以上是关于问一下 16皇后的解法有几种,我的计算机CUP 不够好,计算了好几小时好像算出了有 30多万种,还没算完。求解的主要内容,如果未能解决你的问题,请参考以下文章

16皇后问题有多少解

字节大佬问我TopK,我反手来一句我这有几种解法,您想要哪种?

古代皇后有多少种叫法?

hdu 2553 n皇后问题DFS递归解法

topK的3种解法

搜索总结