递归题目练习---N皇后问题

简介: 递归题目练习---N皇后问题

N皇后问题


参考链接:https://www.cnblogs.com/henuliulei/p/10117304.html(讲解得很详细)


题目描述

请设计一种算法,解决著名的n皇后问题。这里的n皇后问题指在一个nxn的棋盘上放置n个棋子,使得每行每列和每条对角线上都只有一个棋子,求其摆放的方法数。给定一个int n,请返回方法数,保证n小于等于15


基本思路

皇后问题一个重要的判断该点能否取的标准是不能在同一行列和对角。判断约束函数判断第k个后能不能放在x[k]处 两个皇后不能放在统一斜线上: 若2个皇后放置的位置分别是(i,j)和(k,l), 且 i-j = k -l 或 i+j = k+l,则说明这2个皇后处于同一斜线上。


  1. 使用回溯法的思路

对皇后每一行不断进行尝试x[k],判断在此之上的数据时候会发生冲突,如果没有,则k+1.判断下一行。如果发生了冲突,就x[k]++继续进行尝试。当x[k] = = N时,表示此行完全没解,需要回溯到上一行,也就是进行k-1操作,在之前的基础是哪个x[k]++继续进行尝试。

当k = = N时,表明已经实现了一个n皇后的解,将x[k]数据输出则为解。随后,再上一次解的基础上,x[k]再次加一操作,进行下一个解的操作。

当时由于此解的最后一行必然已经没有解,所以k必然会回溯到上一行,k-1,在此摸索x[k]+1的其他解法。如果没有解,则不断的回溯到上一行k,然后再x[k]的基础上再次进行尝试。

知道最后k = =0,返回到第0行,表示已经无解,全部解法已输出。


  1. 使用递归法的思路

使用递归的方法是,对没有一行的位置x[k] = i,依次进行尝试,如果没有冲突,则进行递归进行下一行k+1;,当k = n时说明已经完成一次放置。但是由于处于递归上的其他位置还没有完成,循环没有结束,所以会不断递归查看全部位置是否合适。(感觉有点像广度优先遍历)


代码如下

#include<bits/stdc++.h>
using namespace std;
int n;
int x[100];
int sum=0;
/*
判断第k个后能不能放在x[k]处
两个皇后不能放在统一斜线上:
若2个皇后放置的位置分别是(i,j)和(k,l),
且 i-j = k -l 或 i+j = k+l,则说明这2个皇后处于同一斜线上。
*/
void output(){
    cout << "第" <<sum << "种放置方法为:" << endl;
 for(int i=1;i<=n;i++){
    cout << "(" <<i << "," << x[i] << ")" << endl;
 }
}
int place(int k){
   for(int j=1;j<k;j++){
      if(x[j]==x[k] || abs(x[j]-x[k])== abs(j-k)) //对于此时的x[k],在此之上的同一列和对角线存在冲突
         return 0;  //表示不能放
   }
   return 1;  //表示可以放
}
void BackTrace(int t,int n){//递归
    if(t>n){如果t>n说明已经完成一次放置
        sum++;
        output();
    }
    else{
        for(int i=1;i<=n;i++){
           x[t]=i;
           if(place(t)){// //可以放在i位置处,则继续搜索
              BackTrace(t+1,n);
           }
        }
    }
}
void BackTrace1(int n){//非递归
   int k;
   x[1]=0;
   k=1;
   while(k>=1){
    x[k]+=1;先放在第一个位置
    while((x[k]<=n && !(place(k)))){//如果不能放
        x[k]++;//  //放在下一个位置
    }
    if(x[k]<=n){
        if(k==n){// //如果已经放完了n个皇后
            sum++;
            output();
        }
        else{//  //没有处理完,让k自加,处理下一个皇后
            k++;
            x[k]=0;
        }
    }else{// 当前无法完成放置,则进行剪枝,回溯回去,回到第k-1步
      k--;
    }
   }
}
int main()
{
    memset(x,0,sizeof(x));
    cin >> n;
    cout << n << "皇后的放置方法为" << endl;
    BackTrace(1,n);
    //BackTrace1(n);
    return 0;
}

image.png

目录
相关文章
|
分布式计算 DataWorks NoSQL
DataWorks常见问题之dataworks参数列表太长如何解决
DataWorks是阿里云提供的一站式大数据开发与管理平台,支持数据集成、数据开发、数据治理等功能;在本汇总中,我们梳理了DataWorks产品在使用过程中经常遇到的问题及解答,以助用户在数据处理和分析工作中提高效率,降低难度。
|
11月前
|
存储 域名解析 监控
云上攻防:任意上传、域名接管与AK/SK泄漏
随着企业上云的趋势加剧,云安全成为新的焦点。本文探讨了云计算环境中的三大安全问题:任意上传、域名接管与AK/SK泄漏,分析了这些威胁的工作原理及防护措施,强调了数据保护和访问控制的重要性。通过阿里云等平台的实际案例,提供了具体的安全防范建议。
1394 2
云上攻防:任意上传、域名接管与AK/SK泄漏
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的宠物医院预约挂号系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的宠物医院预约挂号系统的详细设计和实现(源码+lw+部署文档+讲解等)
188 1
|
Cloud Native Java Devops
【Quarkus 技术系列】「云原生架构体系」在云原生时代下的 Java“拯救者”是 Quarkus,那云原生是什么呢?
【Quarkus 技术系列】「云原生架构体系」在云原生时代下的 Java“拯救者”是 Quarkus,那云原生是什么呢?
145 3
|
JSON 安全 算法
JWT的介绍解析
JWT的介绍解析 一、什么是JWT?了解JWT,认知JWT 首先jwt其实是三个英语单词JSON Web Token的缩写。通过全名你可能就有一个基本的认知了。
2325 0
|
弹性计算 小程序 JavaScript
搭建微信小程序(AMD 8代)
本教程提供在阿里云云服务器ECS上基于CentOS 7.9操作系统搭建小程序服务端的指引。
【408数据结构与算法】—折半插入排序(十六)
折半插入排序:查找插入位置时采用折半查找法
【408数据结构与算法】—折半插入排序(十六)
|
存储 JSON 算法
go使用JWT进行跨域认证最全教学
go使用JWT进行跨域认证最全教学
251 0
|
监控 数据中心 流计算
【Flink】(十三)Flink CEP Library 使用案例分析
【Flink】(十三)Flink CEP Library 使用案例分析
257 0