前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >蓝桥杯 试题 基础练习 2n皇后问题(包含n皇后问题讲解)

蓝桥杯 试题 基础练习 2n皇后问题(包含n皇后问题讲解)

作者头像
杨鹏伟
发布2020-09-11 15:09:16
2K0
发布2020-09-11 15:09:16
举报
文章被收录于专栏:ypw

在动手解决2n皇后问题时我们首先先来解决n皇后问题,所谓皇后问题,想必大家都不陌生,就是采用回溯法来实现

思路:以前以为很难的题,现在动手发现也不是很难,思路其实很简单,我们其实可以直接采用一个一维数组,来表示棋盘,因为棋盘上一行只能有一个皇后,所以的话,我们这样子表示的话,直接能表示出每一个皇后在第几行第几列,然后我们就一行行来找,第一行放在第几个,第二行放在第几个…,如此直到找到每一行都有一个皇后的解,然后tot++;然后返回,这一行继续往下找,看看是否还有满足的解,主要的是一个判断函数,就是在这一行之前看看是否有皇后与之同列或者对角线即可。

代码语言:javascript
复制
#include<bits/stdc++.h>
#define N 10 
using namespace std;

int n;//输入n皇后 
int ans[N];
//bool vis[N];
int tot = 0;//用于统计解的个数 

bool check(int ans[],int x,int y){
	bool flag = 0;
	int res; 
	for(int i=1;i<=x-1 && !flag;i++){
		res = ans[i];
		if(res == y || abs(x - i) == abs(y - res))
		   flag = 1;
	}
	return !flag;
}

void dfs(int m){
       if(m == n+1){
       	tot++;
       	return ;
	   }
	   for(int j=1;j<=n;j++){
	   	   if(check(ans,m,j)){//如果不冲突 
	   	     ans[m] = j;
	   	     dfs(m+1);
			}
	   }
	   return ;	
}

int main(){

	cin>>n;
	dfs(1);//从第一行开始
	cout<<tot<<endl;
	return 0; 
} 

那么我们再来看这个2n皇后问题。

思路:在充分理解n皇后问题的基础上,我们对这个题进行分析,本题多了限制条件,有的位置能放皇后,有的位置不能放皇后。思路详细见代码

代码语言:javascript
复制
#include<bits/stdc++.h> 
#define N 10 
using namespace std; 

  
int n;
  
int map_Q[N][N];
  
int posb[N]={0};  
int posw[N]={0}; 
 
int tot = 0;   
 
bool checkw( int cur) //检查函数
{  
    for( int i = 1; i < cur; i++)  
        if( posw[i] == posw[cur] || abs(i-cur) == abs(posw[i]-posw[cur]))  
            return false;  
    return true;  
}   
 
bool checkb( int cur)  //检查函数
{  
    for( int i = 1; i < cur; i++)  
        if( posb[i] == posb[cur] || abs(i-cur) == abs(posb[i]-posb[cur]))  
            return false;  
    return true;  
}  
 
void dfs_white( int cur)  
{  
    if( cur == n+1)  //白皇后也全部放完,次数+1
    {  
        tot++;  
      }
    for( int i = 1; i <= n; i++)  
    {  
        if( posb[cur] == i) //表示第cur列的第i行位置已经被黑皇后占用,
            continue;        //结束当前循环,i+1
        if( map_Q[cur][i] == 0)  //再判断前提条件是否成立
            continue;  
        posw[cur] = i;    //尝试把第cur列的白皇后放在第i行上
        if( checkw(cur))   //判断能否放置白皇后
            dfs_white(cur+1);  //递归
    }  
}  
  
void dfs_black( int cur)  
{  
    if( cur == n+1)  //当黑皇后处理完时,再处理白皇后
    {  
        dfs_white(1);  
    }  
    for( int i = 1; i <= n; i++)  
    {  
       if( map_Q[cur][i] == 0)  //如果第cur列第i行满足放皇后的前提条件即 mp[cur][i] == 1
            continue;  //如果不满足,则结束当前循环,进行下一次循环即i+1。
         posb[cur] = i;     //就尝试把第cur列的黑皇后放在第i行上
        if( checkb(cur))   //然后判断该尝试是否成立,如成立,则进行递归,如不成立,则尝试把当前列的黑皇后放在下一行(i+1行)上。
            dfs_black(cur+1);  //递归
    }  
}  
  
int main(){     
   cin>>n;
   for( int i = 1; i <= n; i++)   //定义棋盘
       for( int j = 1; j <= n; j++)  
           cin>>map_Q[i][j];    

   dfs_black(1);    //先把黑皇后放在第一列
   cout<<tot<<endl; 
   
   return 0;  
}  
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/03/04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档