八皇后编程问题

问题:八皇后

要求:解的输出用八个数字表示,如:基本解{1,5,8,6,3,7,2,4},1代表第一行第一列有皇后,5代表第二行第五列有皇后,以此类推….

解答:

#include<stdio.h> int count=0; int notDanger(int row,int j,int (*chess)[8]) { int i,k,flag1=0,flag2=0,flag3=0,flag4=0,flag5=0; //判断列方向 for(i=0;i<8;i++) { if(*(*(chess+i)+j)!=0) { flag1=1; break; } } //判断左上方 for(i=row,k=j;i>=0&&k>=0;i--,k--) { if(*(*(chess+i)+k)!=0) { flag2=1; break; } } //判断右下方 for(i=row,k=j;i<8&&k<8;i++,k++) { if(*(*(chess+i)+k)!=0) { flag3=1; break; } } //判断右上方 for(i=row,k=j;i>=0&&k<8;i--,k++) { if(*(*(chess+i)+k)!=0) { flag4=1; break; } } //判断左下方 for(i=row,k=j;i<8&&k>=0;i++,k--) { if(*(*(chess+i)+k)!=0) { flag5=1; break; } } if(flag1||flag2||flag3||flag4||flag5) return 0; else return 1; } //参数row表示起始行 //参数n:表示列数 //参数(*chess)[8]表示指向棋盘每一行的指针 void EightQueen(int row,int n,int(*chess)[8]) { int chess2[8][8],i,j; for(i=0;i<8;i++) { for(j=0;j<8;j++) { chess2[i][j]=chess[i][j]; } } if(8==row&&chess2[0][0]==1) { printf("第 %d 种\n",count+1); for(i=0;i<8;i++) { for(j=0;j<8;j++) { if(chess2[i][j]!=0&&i!=7) { printf("%d,",j+1); } if(chess2[i][j]!=0&&i==7) printf("%d",j+1); } //printf("\n"); } printf("\n\n"); count++; } else { //判断这个位置是否有危险 //如果没有危险?继续往下 for(j=0;j<n;j++) { if(notDanger(row,j,chess))//判断是否危险 { for(i=0;i<8;i++) { *(*(chess2+row)+i)=0; } *(*(chess2+row)+j)=1; EightQueen(row+1,n,chess2); } } } } void main() { int chess[8][8],i,j; for(i=0;i<8;i++) { for(j=0;j<8;j++) { chess[i][j]=0; } } EightQueen(0,8,chess); printf("总共有 %d 种解决方法!\n\n",count); }

思考:上面代码的思路是以行为标准,一行一行去填充,只有在某一行确定之后,下一行才能确定。在某一个点,实际上只需要考虑左上方,列方向,右上方,不需要考虑左右下方,因为在填充某一个点的时候,你只知道上面的行是填充了,下面的行还没有填充。上面的代码有些冗余。程序最难理解的还是递归回溯的过程,当满足一行的时候,再递归去计算下一行,直到第8行打印符合的解,某一个符合的解打印完之后,再寻找第8行有没有其它的解,如果没有,退回到第7行,再从第7行开始选择填充的位置。

    原文作者:八皇后问题
    原文地址: https://blog.csdn.net/kobe241314/article/details/78013310
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞