问题背景:
该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。
一个以国际象棋为背景的问题:如何能够在 8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当 n = 1 或 n ≥ 4时问题有解。
问题分析:
可以考虑递归,优化之类的我现在还不会先挖个坑以后补。
1) 建立棋盘即8*8
2) 参数划分(代码借鉴小甲鱼,略有修改)
3) 如何递归
4) 回溯法是什么
代码:
/*
* 八皇后.cpp
*
* Created on: 2015年10月26日
* Author: Snail
*/
#include<stdio.h>
int count=0;
int n=0;
int PrintCheer(int (*cheer)[8]){
for(int i=0;i<8;i++){
for(int j=0;j<8;j++){
printf("%d",(*(*(cheer+i)+j)));
}
printf("\n");
}
}
int Safe(int floor ,int n,int(*cheer)[8]){
int i,j;
int sign=0;
for(i=0;i<8;i++){
if(*(*(cheer+i)+n)){
sign=1;break;
}
}
for(i=floor,j=n;i>=0&&j>=0;i--,j--){
if(*(*(cheer+i)+j)){
sign=1;break;
}
}
for(i=floor,j=n;i<8&&j<8;i++,j++){
if(*(*(cheer+i)+j)){
sign=1;break;
}
}
for(i=floor,j=n;i>=0&&j<8;i--,j++){
if(*(*(cheer+i)+j)){
sign=1;break;
}
}
for(i=floor,j=n;i<8&&j>=0;i++,j--){
if(*(*(cheer+i)+j)){
sign=1;break;
}
}
if(sign){
return 0;
}else{
return 1;
}
}
void EightQuees(int floor,int(*cheer)[8]){
int cheers2[8][8];
for(int i=0;i<8;i++){
for(intj=0;j<8;j++){
cheers2[i][j]=cheer[i][j];
}
}
if(floor==8){
printf("第 %d 种\n",++count);
PrintCheer(cheers2);
printf("\n");
}else{
for(int j=0;j<8;j++){
if(Safe(floor,j,cheers2)){
for(inti=0;i<8;i++){
*(*(cheers2+floor)+i)=0;
}
*(*(cheers2+floor)+j)=1;
EightQuees(floor+1,cheers2);
}
}
}
}
int main(){
int cheers[8][8];
for(int i=0;i<8;i++){
for(intj=0;j<8;j++){
cheers[i][j]=0;
}
}
EightQuees(0,cheers);
return 0;
}