八皇后问题 :假设 將八个皇后放到国际象棋盘上,使其两两之间无法相互攻击。共有几种摆法?
基础知识:
国际象棋里,棋盘为8X8格。
皇后每步可以沿直线、斜线 走任意格。
思路:
1.想把8个皇后放进去,肯定最终每行只有一个皇后,每列只有一个皇后。
2.设个二维数组chess [ i ] [ j ] 模拟棋盘,cas存放摆法。i j 是表示i行j列:
写一个用于递归的函数,思路如下
3.从上往下一行行的放皇后,放下一行时从最左边(第0列)放起,如果不能放就往右挪一格再试。注意判断右边有没有越界出棋盘。
4.写一个函数专门判断当前位置能不能放,只需要判断该位置的横、竖、两对角线,这四条线上有没有其他皇后即可。
5.如果把最后一行放完了,那就统计上这个摆法,cas++。摆完最后一行不能继续判断下一行了。
6.放完一种情况,还要探究其他情况,可以把现在放好的皇后“拿走”,然后再试探 之前没试探过的棋盘格。
下面是递归函数部分:
void queen(int i,int j){ if(j>=line){ //如果右侧越界 return ; } if(check(i,j)==1){//如果能放 chess[i][j]=1;//放皇后 if(i==line-1){//如果是最后一行,记录情况 cas++; } else{ queen(i+1,0);//不是最后一行就分析下一行 } } chess[i][j]=0;//如果此位置不能放,就置空(0),判断旁边的格子。 //如果此位置能放,走到这里就意味着上面的代码全部执行了,把皇后拿走(置零),再讨论其他情况,拿旁边位置试探。 queen(i,j+1); }
(未完待续,明天再写)
#include<stdio.h> #define line 8 void queen(int i,int j); int check(int i,int j); int queennumber=8; int chess[line][line]; int cas=0; int main(){ queen(0,0); printf("%d\n",cas); return 0; } void queen(int i,int j){ if(j>=line){ return ; } if(check(i,j)==1){//如果能放 chess[i][j]=1;//放皇后 if(i==line-1){//如果是最后一行,记录情况 cas++; } else{ queen(i+1,0);//不是最后一行就分析下一行 } } chess[i][j]=0;//如果此位置不能放,就置空(0),判断旁边的格子。 //如果此位置能放,走到这里就意味着上面的代码全部执行了,把皇后拿走(置零),再讨论其他情况,拿旁边位置试探。 queen(i,j+1); } int check(int i,int j){ int k; for(k=0;k<line;k++){ if(chess[i][k]==1) return 0;//0=不能放 } for(k=0;k<line;k++){ if(chess[k][j]==1) return 0; } for(k=-line;k<=line;k++){//两对角线 if(i+k>=0&&i+k<line&&j+k>=0&&j+k<line)//二四象限对角线 if(chess[i+k][j+k]==1) return 0; if(i-k>=0&&i-k<line&&j+k>=0&&j+k<line)//一三象限对角线 if(chess[i-k][j+k]==1) return 0; } return 1; }