算法笔记学习2-全排列和n皇后

#include <stdio.h>
#include <math.h>
const int maxn=11;
int n,a[maxn],hashTable[maxn]={false};
int count=0;
//当前处理排列的第index号位 
void generateP(int index){
	if(index==n+1){//临界条件为一次排列所有的数 
		int i;
		for(i=1;i<=n;++i){
			printf("%d",a[i]);
		}	
		printf("\n");
		return;
	}
	for(int x=1;x<=n;++x){//每次再一个位置试一个数 
		if(hashTable[x]==false){//如果这个数还没有被试
		a[index]=x;//把这个数放放进去
		hashTable[x]=true;//表示这个数以放入
		generateP(index+1);//对index+1位置进行填充,递归填充所有 
		hashTable[x]=false; //对x进行回收,尝试这个位置填入下一个数 
		} 
	}
}
/*
n皇后问题,暴力法 基于全排列算法
全排列保证任意两黄守不会穿线在同一行同一列 
*/ 
void generate (int index){
 //判断临界条件:一次全排列后是否 存在任意两皇后在同一对角线上
 if(index=n+1){
 	int i,j;
 	bool flag=false;
 	for(i=1;i<=n;++i){//i,j表示行号。a[i].a[j]表示列号 
 		for(j=i+1;j<n;j++){//基于比较算法 
 			if(abs(i-j)==abs(a[i]-a[j]))//i-j表示两皇后的行差,a[i -a[j表示两皇后的列差 
 			flag==true;
		 }
	 }
	 if(flag==false)
	 count++;
	 return; 
 } 
 //全排列递归
 int x;
 for(x=1;x<=n;++x){//尝试将1-n充入index
 if(hashTable[x]==false){//x未使用
 a[index]=x;
 hashTable[x]=true;//将x充入index
 generate(index+1);//递归充入index+1
 hashTable[x]=false;//尝试充入下一个数之前要将此hashTable重置 
 } 
 } 
 } 
 /*
 n皇后,回溯法 
 遇见不满足条件的结束递归可以减少时间 
 */
 void generateA(int index){
 	//临界条件  如果能到达此临界则表示成功排列一次
	 if(index==n+1){
	 count++; 
	 return;//这个return在递归里还蛮重要 
	 }
	 for(int x=1;x<=n;++x){//第x行 
	 	//尝试放入每一个数 
	 	if(hashTable[x]==false){//第x行还没有皇后 
	 		bool flag=true;//flag位true表示当前皇后不会和之前的皇后在同一对角线
			 for(int pre=1;pre<index;pre++){//遍历之前的皇后
			 if(abs(pre-index)==abs(x-a[pre])){
			 //第index列皇后的行号位x,第pre列皇后的行号位P[pre] 
			 	flag=false;
			 	break;
			 } 
			 } 
			 if(flag){//如果可以把皇后放在第x行
			 a[index] =x;//令第index列皇后的行号位x
			 hashTable[x]=true;//第x行已被占用
			 generateA(index+1);
			 hashTable[x]=false; 
			 }
		 }
		  
	 }
 }
int main(){
	n=8;
	generateA(1);//从a[1]开始填
	printf("%d\n",count);
	return 0; 
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值