问题描述:
有八个皇后(可以当成八个棋子),如何在 8*8 的棋盘中放置八个皇后,使得任意两个皇后都不在同一条横线、纵线或者斜线上
做法:
从第一行开始,一行一行地考虑,这样起码可以保证皇后不在同一行;
考虑下面的每一行的时候,需要让新增加的棋子不在前面添加的棋子的左下、正下、右下,即新增加的棋子的列不等于前面棋子的列,它的行号+列号不等于前面棋子的行号加列号(不在左下),|行号-列号|不等于之前棋子的|行号-列号|(不在右下);
如果该行所有位置都不符合要求,则回溯到前一行,改变皇后的位置,继续试探;
如果试探到最后一行,所有皇后摆放完毕,则直接打印出 8*8 的棋盘。最后一定要记得将棋盘恢复原样,避免影响下一次摆放。
程序代码:
/*回溯法,8皇后问题*/ #include<stdio.h> #include<iostream> #include<cmath> #include<math.h> using namespace std; int weizhi[8]={0};//用来保存八个棋子的位置 int counts=0; bool check(int hang, int lie); void Queens(int nhang); void print(); int main() { Queens(0); cout<<"8皇后问题的解的个数为:"<<counts<<endl; return 0; } int Check(int line,int list){ //遍历该行之前的所有行 for (int index=0; index<line; index++) { //挨个取出前面行中皇后所在位置的列坐标 int data=weizhi[index]; //如果在同一列,该位置不能放 if (list==data) { return 0; } //如果当前位置的斜上方有皇后,在一条斜线上,也不行 if ((index+data)==(line+list)) { return 0; } //如果当前位置的斜下方有皇后,在一条斜线上,也不行 if ((index-data)==(line-list)) { return 0; } } //如果以上情况都不是,当前位置就可以放皇后 return 1; } //blog.csdn.net/yuer_xiao/article/details/82714734 void Queens(int nhang)//考虑第n行的棋子放置问题 { for(int lie=0;lie<8;lie++) { if(Check(nhang,lie)) { weizhi[nhang]=lie; if(nhang==7) { counts+=1; print(); weizhi[nhang]=0; return; } Queens(nhang+1); weizhi[nhang]=0; } } return;//考虑完全部8个位置,没有符合要求的,返回上一行调用Queens(nhang+1)的地方,使上一行的位置数+1,其实此处不用写return,执行完成之后 } void print() { for (int line = 0; line < 8; line++) { int list; for (list = 0; list < weizhi[line]; list++) printf("0"); printf("#"); for (list = weizhi[line] + 1; list < 8; list++){ printf("0"); } printf("\n"); } printf("================\n"); }
原文地址:https://www.cnblogs.com/za-chen/p/12024927.html
时间: 2024-10-22 20:13:14