算法学步:回溯法-8皇后问题
Posted za-chen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法学步:回溯法-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("
");
}
printf("================
");
}
以上是关于算法学步:回溯法-8皇后问题的主要内容,如果未能解决你的问题,请参考以下文章