n皇后问题(全排列的延伸)

问题 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 的子问题处理完毕,还原 
			
		}
	
	}
	
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值