2、n皇后问题
/*
* n皇后问题,n*n的棋盘上摆放n个皇后,要求任意两个皇后不能冲突,即任意两个皇后不能再同一行、同一列、同一斜线上
* 算法基本思想:将第i个皇后放在第i行,i从1开始,每个皇后都从第1列开始尝试。尝试时判断在该列摆放皇后后是否与前面的皇后冲突,
* 如果没有冲突,则在该列摆放皇后,并考虑摆放下一个皇后;如果有冲突,则考虑下一列。如果该行没有合适的位置,回溯到上一个皇后,
* 考虑在原来位置的下一个位置继续尝试摆放皇后。
* 变量说明,n 皇后数,queen[i] 第i个皇后的位置
*/
#include<stdio.h>
#include <stdlib.h>
#define n 4
int queen[n + 1];
void Show() {
int i;
printf("(");
for (i = 1; i <= n; i++) {
printf("%d", queen[i]);
}
printf(")\n");
}
int Place(int j) {
int i;
for (i = 1; i < j; i++) {
//判断放在该列与前面已拜访的皇后是否冲突,同列冲突和斜线冲突,冲突则不能放在该列
if (queen[i] == queen[j] || abs(queen[i] - queen[j]) == j - i) {
return 0;
}
}
return 1;
}
void Nqueen(int j) {
int i;
for (i = 1; i <= n; i++) {
queen[j] = i;
if (Place(j)) {
printf("第%d个皇后摆放在第%d列,没问题\n", j, i);
if (j == n) {
printf("摆放完%d个皇后都没问题,展示摆放位置\n", n);
Show();
}
else {
Nqueen(j + 1);
}
}
printf("第%d个皇后摆放在第%d列,与前面的皇后有冲突\n", j, i);
}
}
int main() {
Nqueen(1);
return 0;
}
运行结果
第1个皇后摆放在第1列,没问题
第2个皇后摆放在第1列,与前面的皇后有冲突
第2个皇后摆放在第2列,与前面的皇后有冲突
第2个皇后摆放在第3列,没问题
第3个皇后摆放在第1列,与前面的皇后有冲突
第3个皇后摆放在第2列,与前面的皇后有冲突
第3个皇后摆放在第3列,与前面的皇后有冲突
第3个皇后摆放在第4列,与前面的皇后有冲突
第2个皇后摆放在第3列,与前面的皇后有冲突
第2个皇后摆放在第4列,没问题
第3个皇后摆放在第1列,与前面的皇后有冲突
第3个皇后摆放在第2列,没问题
第4个皇后摆放在第1列,与前面的皇后有冲突
第4个皇后摆放在第2列,与前面的皇后有冲突
第4个皇后摆放在第3列,与前面的皇后有冲突
第4个皇后摆放在第4列,与前面的皇后有冲突
第3个皇后摆放在第2列,与前面的皇后有冲突
第3个皇后摆放在第3列,与前面的皇后有冲突
第3个皇后摆放在第4列,与前面的皇后有冲突
第2个皇后摆放在第4列,与前面的皇后有冲突
第1个皇后摆放在第1列,与前面的皇后有冲突
第1个皇后摆放在第2列,没问题
第2个皇后摆放在第1列,与前面的皇后有冲突
第2个皇后摆放在第2列,与前面的皇后有冲突
第2个皇后摆放在第3列,与前面的皇后有冲突
第2个皇后摆放在第4列,没问题
第3个皇后摆放在第1列,没问题
第4个皇后摆放在第1列,与前面的皇后有冲突
第4个皇后摆放在第2列,与前面的皇后有冲突
第4个皇后摆放在第3列,没问题
摆放完4个皇后都没问题,展示摆放位置
(2413)
第4个皇后摆放在第3列,与前面的皇后有冲突
第4个皇后摆放在第4列,与前面的皇后有冲突
第3个皇后摆放在第1列,与前面的皇后有冲突
第3个皇后摆放在第2列,与前面的皇后有冲突
第3个皇后摆放在第3列,与前面的皇后有冲突
第3个皇后摆放在第4列,与前面的皇后有冲突
第2个皇后摆放在第4列,与前面的皇后有冲突
第1个皇后摆放在第2列,与前面的皇后有冲突
第1个皇后摆放在第3列,没问题
第2个皇后摆放在第1列,没问题
第3个皇后摆放在第1列,与前面的皇后有冲突
第3个皇后摆放在第2列,与前面的皇后有冲突
第3个皇后摆放在第3列,与前面的皇后有冲突
第3个皇后摆放在第4列,没问题
第4个皇后摆放在第1列,与前面的皇后有冲突
第4个皇后摆放在第2列,没问题
摆放完4个皇后都没问题,展示摆放位置
(3142)
第4个皇后摆放在第2列,与前面的皇后有冲突
第4个皇后摆放在第3列,与前面的皇后有冲突
第4个皇后摆放在第4列,与前面的皇后有冲突
第3个皇后摆放在第4列,与前面的皇后有冲突
第2个皇后摆放在第1列,与前面的皇后有冲突
第2个皇后摆放在第2列,与前面的皇后有冲突
第2个皇后摆放在第3列,与前面的皇后有冲突
第2个皇后摆放在第4列,与前面的皇后有冲突
第1个皇后摆放在第3列,与前面的皇后有冲突
第1个皇后摆放在第4列,没问题
第2个皇后摆放在第1列,没问题
第3个皇后摆放在第1列,与前面的皇后有冲突
第3个皇后摆放在第2列,与前面的皇后有冲突
第3个皇后摆放在第3列,没问题
第4个皇后摆放在第1列,与前面的皇后有冲突
第4个皇后摆放在第2列,与前面的皇后有冲突
第4个皇后摆放在第3列,与前面的皇后有冲突
第4个皇后摆放在第4列,与前面的皇后有冲突
第3个皇后摆放在第3列,与前面的皇后有冲突
第3个皇后摆放在第4列,与前面的皇后有冲突
第2个皇后摆放在第1列,与前面的皇后有冲突
第2个皇后摆放在第2列,没问题
第3个皇后摆放在第1列,与前面的皇后有冲突
第3个皇后摆放在第2列,与前面的皇后有冲突
第3个皇后摆放在第3列,与前面的皇后有冲突
第3个皇后摆放在第4列,与前面的皇后有冲突
第2个皇后摆放在第2列,与前面的皇后有冲突
第2个皇后摆放在第3列,与前面的皇后有冲突
第2个皇后摆放在第4列,与前面的皇后有冲突
第1个皇后摆放在第4列,与前面的皇后有冲突
所谓回溯法,本来摆放第i个皇后的位置没问题的,因为再摆放后面的皇后找不到满足条件的位置,就把前面摆放的第i个皇后的位置换成下一个。
例如将第1个皇后摆放在第1列,没问题。一直去寻找后面3个皇后的位置的摆放位置时,找不到合适的位置,就认为,第1个皇后摆放在第1列有问题。让第1个皇后,摆放在第2行,结果经过后面的寻找,剩余3个皇后都找到了合适的位置就完事了。 说明第1个皇后摆放在第2行是正确的。最终找到(2413)满足条件的位置,所谓(2413)意思就是第一个皇后摆放在第2列,第2个皇后摆放在第4列,第3个皇后摆放在第1列,第4个皇后摆放在第3列。
第一次回溯,是摆放了(13…)时,即第1个皇后摆放在第1列,第2个皇后摆放在第3列,觉得没问题,但发现当摆放第3个皇后时,发现从第3行中找不到能摆放的位置都有冲突,
于是当初 Nqueen(j + 1); j=2, 摆放第3个皇后,递归完成跳出来,就执行下面这一句
printf("第%d个皇后摆放在第%d列,与前面的皇后有冲突\n", j, i);
打出来就是
第2个皇后摆放在第3列,与前面的皇后有冲突。 这里其实不是因为与前面的皇后有冲突,而是,按照目前的摆法,后面的皇后没位置放。因此就回溯到第2个皇后,看看摆放在第4行,有没有问题。显然是没问题的,因为第2个皇后摆放在第4行与前面摆放的皇后不冲突,前面只摆放了1个皇后在第1行第一列。那么就看看后面剩下的2个能不能摆放下。
如果第2个皇后摆在第4列,后面的2个皇后还是没正确的位置摆放的话,那么,就跳出了,当初 Nqueen(j + 1); j=1时,第2个皇后摆放的递归。 就看第1个皇后摆放在第2行的情况了…
python用递归实现阶乘运算
#递归实现阶乘
def f1(n):
if(1 == n or 0 == n):
return 1
else:
return n*f1(n-1)
print(f1(5))
如何去解释呢?
f1(5),压栈
5f(4),压栈
4f(3),压栈
3f(2),压栈
2f(1)=2
f(2)出栈,结果是21 =2
f(3)出栈,结果是321=6
f(4)出栈,结果是4321=24
f(5)出栈,结果是54321=120,程序执行结束,退出。