C语言 八皇后问题的解决

八皇后的问题描述:

     在 8 X 8 方格的棋盘中 ,每一行 中 有一个皇后旗子, 该旗子的 横、 竖、左倾斜、右倾斜的位置都是不能存在其他的旗子, 问有多少种摆法?

百度百科介绍

解决的思路

   1. 固定到一行,依次选择下一列

   2. 当选择一个位置的时候,需要 判断 该棋子位置的行方向 列方向 对角倾斜的方向 有没有其他的棋子, 如果有,则 换下对应列的位置

解决代码如下

#include <stdio.h>
#include <stdlib.h>

int count = 1;

// 判断当前的位置 是否危险
// 0 是危险
// 1 不危险
// row 是当前的行 y
// column 当前的列 x
int isExistChess(int row, int column, int (*chess)[8]){
  int z;
  int x3 = row, y3 = column;
  int x4 = row, y4 = column;

  // 正上
  for(z = row; z >= 0; z--){
    if(chess[z][column] == 1){
      return 0;
    }
  }

  // 正左
  // for(z = column; z >= 0; z--){
  //   if(chess[row][z] == 1){
  //     return 0;
  //   }
  // }

  // 左上
  while(x3 >= 0 && y3 >= 0){
    if(chess[x3][y3] == 1){
      return 0;
    }
    x3 -= 1;
    y3 -= 1;
  }

  // 右上
  while(x4 >= 0 && y4 < 8){
    if(chess[x4][y4] == 1){
      return 0;
    }
    x4 -= 1;
    y4 += 1;
  }

  return 1;
}

void ChessErgodic(int row, int (*chess)[8]){
  int tmpchess[8][8], x, y;

  for(x = 0; x < 8; x++){
    for(y = 0; y < 8; y++){
      *(*(tmpchess + x) + y) = *(*(chess + x) + y);
    }
  }
  if(8 == row){
    printf("第%d种:\n", count++);
    for(x = 0; x < 8; x++){
      for(y = 0; y < 8; y++){
        printf("%d  ", *(*(tmpchess + x) + y));
      }
      printf("\n");
    }
    printf("\n");
  } else {
    for(y = 0; y < 8; y++){
      for(x = 0; x < 8; x++){
        *(*(tmpchess + row) + x) = 0;
      }
      if(isExistChess(row, y, tmpchess)){
        *(*(tmpchess + row) + y) = 1;
        ChessErgodic(row + 1, tmpchess);
      }
    }
  }
}

int main(int argc, char const *argv[])
{
  int chess[8][8], x, y;

  // 初始化棋盘
  for(x = 0; x < 8; x++){
    for(y = 0; y < 8; y++){
      chess[x][y] = 0;
    }
  }
  ChessErgodic(0, chess);

  return 0;
}

结果:

...

第92种:
0  0  0  0  0  0  0  1  
0  0  0  1  0  0  0  0  
1  0  0  0  0  0  0  0  
0  0  1  0  0  0  0  0  
0  0  0  0  0  1  0  0  
0  1  0  0  0  0  0  0  
0  0  0  0  0  0  1  0  
0  0  0  0  1  0  0  0  

可以看出,总共有 92 中摆放方法 ,高斯先生都算不全的东西,使用编程就能很好的解决

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值