八皇后——递归学习

问题背景:

该问题是国际西洋棋棋手马克斯·贝瑟尔于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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值