ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

蓝桥杯试题 基础练习 2n皇后问题以及n皇后问题

2022-02-04 23:03:41  阅读:111  来源: 互联网

标签:int 蓝桥 maxn 坐标 皇后 2n col


在学习2n皇后之前,我们应该认识一下n皇后问题:

在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
输入样例:
1
8
5
0
输出样例:
1
92
10

可以这么理解,以4皇后为例子:

现在剩下的问题是通过一些必要的操作使得这个算法的运算效率变高,这就是剪枝;

可以这样认为,设起始第一行第一列放皇后并设其坐标是(0,0),设放皇后的坐标为(i,j),为了避免重复,新皇后的坐标是(r,c),

可以看到:为了避免同列j!=c;

然后同行我们可以不用比较(因为我们是遵循着每一行只放一个皇后的原则摆放);

假设从放皇后的坐标到新皇后的坐标斜着走a步,那有新皇后坐标相对于皇后坐标来讲的话就有左上(i-r,j-c),左下(i-a,j+a),右下(i+a,j+a),右上(i+a,j-a),无论如何,都是|i-r|=|j-c|;

那为了满足题目要求就有|i-r|!=|j-c|;

题目就明确了,代码如下:

#include<bits/stdc++.h>
using namespace std;
int col[12]={0};  //col数组用于存放第i行第col[i]列放置皇后。
int n,tot = 0;        //设置全局变量,即可不用投值,直接调用
bool check(int r,int c){        //判断新皇后是否和放好的皇后发生冲突。
    for(int i=0;i<r;i++){
        //这里不需要判断是否同行,因为我们设置的每行只投放一个皇后,所以不需要判断,只判断是否同列或者同斜线即可。
        if((col[i]==c)||(abs(col[i]-c)==abs(i-r)))return false;
    }
    return true;
}
void dfs(int r){
    if(r==n){ //因为从0开始,当行数r达到n时,表示已经完成了
        tot++;
        return ;
    }
    for(int c=0;c<n;c++){
        if(check(r,c)){ //判断是否可以放置,可以便放置,否则剪枝。
            col[r]=c;
            dfs(r+1);    //继续放置下一行的新皇后
        }
    }
}
int main(){
    int ans[12]={0};
    for(n=0;n<=10;n++){             //对n皇后进行打表,然后结果存入ans数组
        memset(col,0,sizeof(col));     //每次要进行初始化
        tot=0;
        dfs(0);                    //DFS
        ans[n]=tot;                //存放
    }
    while(cin >> n){
        if(n==0)return 0;
        cout << ans[n] << endl;
    }
    return 0;
}

并且附上一个讲的很好的视频链接:https://www.bilibili.com/video/BV1bK4y1n7iq?spm_id_from=333.999.0.0

接下来就是2n皇后问题了,大体思路和n皇后问题差不多了,不同之处是需要判断能不能放皇后,那我们可以如下解决:

在放完了黑皇后(先放黑)在处理白皇后,其中如果没放完的话判断能不能放皇后这样一个问题,然后对于白皇后我们除了判断能不能放皇后的同时也要判断那个位置是不是被黑皇后占了

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 10;  
int n;  
int mapqueen[maxn][maxn];  //能不能放皇后 
int whqueen[maxn]={0};  //白皇后位置 
int blqueen[maxn]={0};  //黑皇后位置 
int ans; 
bool checkbl(int step,int c)
{
    for(int i=1;i<step;i++)
    {
        if(blqueen[i]==c||(abs(blqueen[i]-c)==abs(i-step)))
        return false;
    }
    return true;
}
bool checkwh(int step,int c)
{
    for(int i=1;i<step;i++)
    {
        if(whqueen[i]==c||(abs(whqueen[i]-c)==abs(i-step)))
        return false;
    }
    return true;
}
void dfs_white(int step)
{
    if(step==n+1)
    {
        ans++;
    }
    for(int c=1;c<=n;c++)
    {
        if(blqueen[step]==c)
        continue;
        if(mapqueen[step][c]==0)
        continue;
        whqueen[step]=c;
        if(checkwh(step,c))
        {
            dfs_white(step+1); 
        }
    }
}
void dfs_black(int step)
{
    if(step==n+1)
    {
        dfs_white(1);
    }
    for(int c=1;c<=n;c++)
    {
        if(mapqueen[step][c]==0)//第step行第i列是否放了皇后的条件 
        continue;
        blqueen[step]=c;//在第step行第i列放黑皇后
        if(checkbl(step,c))
        {
            dfs_black(step+1);//进入下一层 
         } 
    }
 } 
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&mapqueen[i][j]);
        }
    }
    dfs_black(1);//从第一行开始搜黑皇后 
    printf("%d\n",ans); 
    return 0;
}

 

标签:int,蓝桥,maxn,坐标,皇后,2n,col
来源: https://www.cnblogs.com/LQS-blog/p/15863573.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有