问题描述:
在一个在n×n的棋盘上放n个皇后,要求任意两个皇后都不在棋盘的同一行、列和对
角线上(即按国际象棋规则,使得皇后间互不攻击),试给出一个递归算法求出n个皇后全部
的放置方法。
算法设计:
给定n×n的棋盘(假定n=4),用递归算法求出n个皇后全部的放置方法。每个皇后的
位置用(k,x(k))表示,k表示行号,x(k)表示列号。为方便起见,输出结果的行号和列号都
从1开始。
数据输入:
无。
结果输出:
将计算出的n个皇后的全部放置方法分行输出。每种方法的输出形
式是x(1)x(2)x(3)x(4),即从上至下输出每个皇后的列号,最后一行输出总的放置方法
数目。
输出文件示例:
2413
3142
2
思路
用(x,y)的形式表示棋盘上的每一格,x表示行,y表示列。首先在棋盘的第一行第
一列放置第一个皇后,然后在棋盘的第二行中的每一列开始试探放第二个皇后,判断第二个
皇后处于某一列时,是否与前面放置好的皇后存在互相攻击的情况,若不存在,那么依照相
同的方法开始在下一行递归进行下一个皇后放置;若存在,那么接着试探下一列,直到这一
行的全部列被试探完为止。
#include<iostream>
#include<algorithm>
#include<iterator>
#include<vector>
using namespace std;
int
n_queen(int k);
int main()
{
int k = 0;
cin >> k;
int a = n_queen(k);
cout << a << endl;
}
int
n_queen(int k)
{
static vector<int> ivec(k, 0);
int total = 0;
for(int i = 1; i <= ivec.size(); ++i)
{
int flag = 0; // 冲突标志
ivec[k - 1] = i;
// 检查同一列是否有冲突的皇后
for(int j = ivec.size(); j > k; --j)
{
// 同一列中有两个皇后,冲突
if(ivec[j - 1] == i)
{
flag = 1;
break;
}
}
// 列冲突
if(flag)
{
ivec[k - 1] = 0;
continue;
}
// 对角线是否冲突
else
{
int row = k;
int column1 = i + 1; // 左对角线
int column2 = i - 1; // 右对角线
while(row < ivec.size())
{
if(column1 > 0)
{
if(ivec[row] == column1)
{
flag = 1;
break;
}
}
if(column2 > 0)
{
if(ivec[row] == column2)
{
flag = 1;
break;
}
}
++row;
++column1;
--column2;
}
if(flag)
{
ivec[k - 1] = 0;
continue;
}
}
if(k == 1) // 递归出口
{
for(int a = 0; a < ivec.size(); ++a)
cout << ivec[a] << " ";
cout << endl;
return 1;
}
// 现在列没有冲突的皇后,对角线也没有冲突的皇后,因此当前皇后位置正确,开始找上一行的皇后
else
total += n_queen(k - 1);
}
return total;
}