蓝桥杯-2n皇后问题——算法笔记

本文是关于蓝桥杯比赛中的2n皇后问题的算法笔记。通过深度优先搜索(DFS)解决,首先安排黑皇后的位置,然后安排白皇后。关键代码在于检查皇后是否在同一列或对角线上,避免冲突。代码实现简洁,使用一维数组记录黑白皇后位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

“2n皇后”问题本质上还是 用 dfs 写“8皇后”问题。
先确定黑皇后的排列,再确定白皇后的排列。

此代码特色:
1)用一维数组posb[maxn]、posw[maxn]即可表示黑白皇后的摆放。
eg. posb[2]=1 表示黑皇后在第二行第一列放一枚。
2)if( posw[i] == posw[cur] || abs(i-cur) == abs(posw[i]-posw[cur]))
这个是本程序的关键代码。可判断是否有同列(不可能同行),左右斜对角线的皇后。

完整代码:



#include<cmath>  
#include<iostream>  
using namespace std; 
 
const int maxn = 10;  
int n;  
int map_Q[maxn][maxn];  
int posb[maxn]={0};  
int posw[maxn]={0};  
int ans;   
 
bool checkw( int cur) //检查函数
{  
    for( int i = 1; i < cur; i++)  
        if( posw[i] == posw[cur] || abs(i-cur) == abs(posw[i]-posw[cur]))  
        //关键!关键!关键!
		// 通过 i 来循环 1~ cur-1层 
		// posb[i] == posb[cur]	控制不在同一列
		//本身不可能在同一行
		// abs(i-cur) == abs(posb[i]-posb[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]))  		
		//关键!关键!关键!
		// 通过 i 来循环 1~ cur-1层 
		// 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
    {  
        ans++;  
    }
    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++)  		//表示 放第 cur行的 第 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];    
   ans = 0;  
   dfs_black(1);    //先把黑皇后放在第一列
   cout<<ans<<endl; 
   
    return 0;  
}  





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值