利用回溯法解决八皇后问题

#利用回溯法解决八皇后问题
这个地方的回溯不好理解,强调一下
为什么回溯
假如现在放的是第六个皇后,其实是在check(第5个皇后)中调用了check(第6个),从第一列位置开始尝试放置皇后,直到最后一个位置都在冲突,必须修改上一个皇后的位置才能解决。
check(第6个)这一段代码就结束了,继续执行check(第5个皇后)未执行完的代码,即回溯。
又假如现在成功放置完最后一个皇后,那么最内层被调用的check结束,回到倒数第二层函数继续执行。也就是尝试将前面皇后位置后移,得到所有结果。

如何理解回溯
举一个看上去更轻松的例子。

void A(){
B();
t++();
}
void B(){
C();
i++;
}

A执行,B被调用,C被调用
C结束 ,先把B中i++执行完毕,
B结束,再将A中代码执行完毕。
递归和回溯本质上都是函数调用,自己调自己
区别是递归最后一次调用结束,回到倒数第二次调用,依次回到第一次调用;回溯是在回退过程中,再次调用下一层的函数,看代码,假如不是在调用本身

void A(){
B();
t++();
}
void B(){
C();
i++;
C();//再次调用C,八皇后中是循环调用C,直到循环结束
}

附上完整C++代码

#include <iostream>
#include <math.h>
using namespace std;
int m = 8;

int c = 0;
int queen8[8];
void print();
bool judge(int n);//判断放置第n个皇后时,有没有攻击
void check(int n);//
int main()
{
	check(0);
	cout << "共有" << c << "种解法" << endl;
	return 0;
}
//首先是第一个皇后,将第一个皇后放在第一列,判断当前已放置皇后(还未放置,一
//定不攻击)与第一个皇后是否攻击;将第二个皇后放到1格子,判断是攻击状态,
//将第二个皇后放到2格子,判断是攻击状态,再继续放后放...直到不攻击位置。
//当放入第n个皇后,每个位置都是攻击状态时,进行回溯。
void check(int n) {
	if (n == m) {

		print();
		return;
	}
	for (int i = 0; i < m; i++) {
		queen8[n] = i;
		if (judge(n))
			check(n + 1);
			
	}

}

void print() {
	c++;
	for (int i = 0; i < m; i++) {
		cout << queen8[i] << " ";
	}

	cout << endl;
}
//判断放置第n个皇后时,有没有攻击
bool judge(int n) {
	int j;
	for (j = 0; j < n; j++) { 
		if (queen8[j] == queen8[n] || abs(queen8[j] - queen8[n]) == abs(j - n))
			return false;
	}
	return true;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值