1
问题 D: 【递归入门】n皇后 问题(原始的8皇后问题)
时间限制: 1 Sec 内存限制: 128 MB
提交: 926 解决: 436
[提交][状态][讨论版][命题人:外部导入]
题目描述
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。
输入
一个整数n( 1 < = n < = 10 )
输出
每行输出对应一种方案,按字典序输出所有方案。每种方案顺序输出皇后所在的列号,相邻两数之间用空格隔开。如果一组可行方案都没有,输出“no solute!”
图一
如上图以a对应的排列为2、4、1、3、5;b对应的排列为3、5、1、4、2
样例输入
4
样例输出
2 4 1 3
3 1 4 2
2 解析
- 题目:给定范围1~N内的全排序中,求出每一个排列中每个元素与该排列中其他的元素不在横、竖、斜线上的排列方案
- 思路一:枚举1~N的全排列,每列举完一组,然后就在该组排列中测试当前方案是否合法(排列中每个元素与该排列中其他的元素不在横、竖、斜线上)
- 思路二:在上一种的方案的前提下,进行回溯法优化,在每次全排列列举每一组元素时候,每列举一个元素,就判断一次是否和之前的元素冲突(排列中每个元素与该排列中其他的元素在横、竖、斜线上),如果不冲突就将元素放进该组中;如果冲突,就直接列举下一组
3 参考代码
- 思路一:
#include <cstdio>
#include <cstdlib>
const int MAXN = 100;
int N;
bool hashTable[MAXN] = {false};
int P[MAXN];
int count = 0;
void DFS(int index){//朴素算法
if(index == N + 1){
bool flag = true;//flag为true,表示当前方案合法
for (int i = 1; i <= N ; ++i)//遍历两个皇后,
{
for (int j = i + 1; j <= N; ++j)
{
//第四象限内,P[y]为纵坐标,i、j为横坐标
if(abs(i - j) == abs(P[j] - P[i])){//如果在一条对角线上,也就是正方形相对的两个端点
flag = false;
}
}
}
if(flag == true) {
count++;
for (int i = 1; i <= N; ++i)
{
printf("%d", P[i]);
if(i <= N - 1) printf(" ");
}
printf("\n");
}
}
for (int i = 1; i <= N; ++i)//全排列
{
if(hashTable[i] == false){
P[index] = i;
hashTable[i] = true;
DFS(index + 1);
hashTable[i] = false;
}
}
}
int main(){
scanf("%d", &N);
DFS(1);
if(count == 0) printf("no solute!\n");
return 0;
}
- 思路二:
#include <cstdio>
#include <cstdlib>
const int MAXN = 100;
int N;
bool hashTable[MAXN] = {false};
int P[MAXN];
int count = 0;
void DFS(int index){//朴素算法
if(index == N + 1){
count++;
for (int i = 1; i <= N; ++i)
{
printf("%d", P[i]);
if(i <= N - 1) printf(" ");
}
printf("\n");
return;
}
for (int i = 1; i <= N; ++i)//第i行
{
if(hashTable[i] == false){
bool flag = true;
for (int pre = 1; pre < index; ++pre)
{
//第index列的皇后行号为i,第pre列的行号为P[pre]
if(abs(index - pre) == abs(P[pre] - i)){
flag = false;
break;
}
}
if(flag == true){
P[index] = i;
hashTable[i] = true;
DFS(index + 1);
hashTable[i] = false;
}
}
}
}
int main(){
scanf("%d", &N);
DFS(1);
if(count == 0) printf("no solute!\n");
return 0;
}