递归概述:
1.自身调用自身。
2.有明确的终止条件。
3.无需考虑程序运行过程,默认程序可以按照逻辑执行。
示例如下:
N皇后问题描述:输入一个正整数N,要求N个皇后摆在国际象棋的N*N的棋盘上,要求N个皇后互相不能进攻,要求输出所有的摆放方式(同行,同列,同对角线都可以进攻)。
问题分析:
1.首先该问题为标准递归问题,需要明确的终止条件,及第N个皇后摆放好后return。
2.皇后摆放方式的判断,同行,同列,同对角线上的皇后都是互斥的。
3.当一个皇后摆放好后,存储当前皇后位置,并向下递归,直到N个皇后位置都摆放好。
#include "iostream"
#include "math.h"
using namespace std;
void N_Queen(int kqueen);
int N;
int QueenPos[100]; //维护一个存储皇后”列数“数的数组,数组下标代表“行数”
int main()
{
int ncase;
freopen("input.txt", "r", stdin);
cin >> ncase;
for (int i = 0; i < ncase; i++)
{
cin >> N;
N_Queen(0);
}
return 0;
}
void N_Queen(int kqueen) //0-kqueen-1个皇后的位置全部放置妥当
{
if (kqueen == N)
{
for (int i = 0; i < N; i++)
{
cout << QueenPos[i] + 1 << " ";
}
cout << endl;
return ;
}
for (int i = 0; i < N; i++)
{ //皇后的摆放的位置可以是从0-N-1列
int j;
for (j = 0; j <kqueen ; ++j) //0到kqueen-1行的皇后是已经摆放好的,
//和已经摆放好的kqueen-1个皇后进行比较,看是否与摆放好的0到kqueen-1行皇后发生冲突。
if (QueenPos[j] ==i) //若与摆放好的皇后同一行,则发生冲突。
{
break;
}
if (abs(QueenPos[j]-i)==abs(j-kqueen)) //若与摆放好的皇后是处于对角线位置,则发生冲突。
{
break;
}
}
if (kqueen == j) //如果与前kqueen-1个皇后都不冲突,则存将kqueen个皇后存储到QueenPos数组中。
{
QueenPos[kqueen] = i;
N_Queen(kqueen + 1); //继续寻找下一个皇后的位置
}
}
}