问题 D: 【递归入门】n皇后 问题(原始的8皇后问题)
时间限制: 1 Sec 内存限制: 128 MB
提交: 588 解决: 281
[提交][状态][讨论版][命题人:外部导入]
题目描述
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。
输入
一个整数n( 1 < = n < = 10 )
输出
每行输出对应一种方案,按字典序输出所有方案。每种方案顺序输出皇后所在的列号,相邻两数之间用空格隔开。如果一组可行方案都没有,输出“no solute!”
样例输入
4
样例输出
2 4 1 3 3 1 4 2
C++实现版本:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=10010;
int n,a[maxn];
int main(){
int n,cnt=0;
cin>>n;
for(int i=1;i<=n;i++)
a[i]=i;
do{
int flag=1;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(abs(i-j)==abs(a[i]-a[j]))
flag=0;
}
}
if(flag){
cnt=1;
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
}while(next_permutation(a+1,a+n+1));
if(cnt==0) cout<<"no solute!"<<endl;
return 0;
}
递归版:
快被坑死了,刚开始散列数组设定的hash,提交的时候一直编译错误,然后也找不到问题的所在,后来改成hashTable对了。。
才知道hash 也是c++的一个库函数。。。。。。。。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=10010;
int n,P[maxn],cnt=0;
bool hashTable[maxn]={false};
void generateP(int idx){//全排列就相当于往一个数组里不断的填数
if(idx==n+1){//当产生一个排列后 判断是不是满足条件的排列
int flag=1;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(abs(i-j)==abs(P[i]-P[j]))//如果在同一条斜线上
flag=0;
}
}
if(flag){
cnt=1;
for(int i=1;i<=n;i++)
cout<<P[i]<<" ";
cout<<endl;
}
return ;
}
for(int i=1;i<=n;i++){
if(hashTable[i]==false){
hashTable[i]=true;
P[idx]=i;
generateP(idx+1);
hashTable[i]=false;
}
}
}
int main(){
cin>>n;
generateP(1);//从1下标开始产生排列
if(cnt==0) cout<<"no solute!"<<endl;
return 0;
}
剪枝版:
void generateP(int idx){//全排列就相当于往一个数组里不断的填数
if(idx==n+1){//
cnt=1;
for(int i=1;i<=n;i++)
cout<<P[i]<<" ";
cout<<endl;
return ;
}
for(int i=1;i<=n;i++){
if(hashTable[i]==false){
int flag=1;//在选择皇后的位置的时候就判断这个位置和已经放皇后的位置是否位于同一条斜线
for(int pre=1;pre<idx;pre++){
if(abs(pre-idx)==abs(P[pre]-i)){
flag=0;
break;
}
}
if(flag==0) continue;//若位于同一条斜线则表明该种情况以后的各个分问题都不需要再考虑
hashTable[i]=true;
P[idx]=i;
generateP(idx+1);//处理下一个位置
hashTable[i]=false;//当递归返回至此,表明idx下标为i 的子问题处理完毕,还原
}
}
}