回溯算法(3)--n皇后问题及回溯法相关习题

news2024/11/24 16:27:27

一、n皇后问题

1、概述

        n皇后要求在一个n×n的棋盘上放置n个皇后,使得他们彼此不受攻击,皇后可以攻击同一行、同一列、同一斜线上的敌人,所以n皇后问题要求寻找在棋盘上放置这n个皇后的方案,使得任意两个皇后都不在同一行、同一列或同一斜线上。

2、子集树解法

(1)判断是否遍历过叶子结点(t>n),若没有则遍历子集树,判断place(t),即该层从1到n是否存在有成立的情况。

(2)place剪枝函数,遍历1到t,如果存在一个点满足同一列,同一对角线,那么舍弃这个叶节点,反之保留叶节点。由于每一层保存的点存放在x数组,该数组显性约束了不满足同一行的条件,数组中的索引+1就是行号,数组值为列号。

(3)若已经满足t>n,即已经遍历过叶子结点,则输出该可行解。

3、排列树解法

(1)判断是否遍历过叶子结点(t>n),若没有则遍历排列树,对后续层进行全排列,判断place(t),即该层从1到n是否存在有成立的情况。

(2)place剪枝函数,此时由于对后续层全排列,第一层的列数不能存在于后续层,不需要添加同一列的检查,其他与子集树一致。

(3)若已经满足t>n,即已经遍历过叶子结点,则输出该可行解。

4、代码

//n皇后问题
import java.util.Scanner;
public class Queen {
   static int x[]=new int[100];
   static int n;
   static int sum=0;
   public static void main(String [] args)
   {
        
        n=new Scanner(System.in).nextInt();
        //排列树提前添加x数组值,保证能够进行排列
        for(int i=1;i<=n;i++)
            x[i]=i;
        Backstack2(1);
   } 
   //子集树算法
   public static void Backstack(int t)
   {
        if(t>n)
        {
            sum++;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(x[i]==j)
                        System.out.print("Q ");
                    else    
                        System.out.print(". ");
                }
                System.out.println();
            }
            System.out.println();
        }
        else
        {
            for(int i=1;i<=n;i++)
            {
                x[t]=i;
                if(place(t))
                    Backstack(t+1);
            }
        }
   }
   public static boolean place(int t)
   {
        for(int i=1;i<t;i++)
            if((Math.abs(x[i]-x[t])==Math.abs(i-t))||x[i]==x[t])
                return false;
        return true;
   }
   //排列树算法
   public static void Backstack2(int t)
   {
        if(t>n)
        {
            sum++;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(x[i]==j)
                        System.out.print("Q ");
                    else    
                        System.out.print(". ");
                }
                System.out.println();
            }
            System.out.println();
        }
        else{
            for(int i=t;i<=n;i++)
            {
                
                swap(i,t);
                if(place2(t))
                    Backstack2(t+1);
                swap(i,t);
                
            }
        }
   }
   public static void swap(int i,int t)
   {
        int tmp=x[i];
        x[i]=x[t];
        x[t]=tmp;
   }
   public static boolean place2(int t)
   {
        for(int i=1;i<t;i++)
        {
            if(Math.abs(x[i]-x[t])==Math.abs(i-t))
                return false;
        }
        return true;
   }
}

5、结果

        通过Q和 . 区分皇后的位置。

二、含重复元素的全排列

1、概述

        给定一个可包含重复数字的序列,按任意顺序返回所有不重复的全排列,如:输入【1,1,2】,输出【1,1,2】,【1,2,1】,【2,1,1】。

2、算法

        排列树问题,在原有问题上添加条件x[t]==x[i]&&t!=i,当前交换的两个数若相同,且不是同一个数,则剪枝,注意循环中使用continue,表示下面的交换和扩展的操作不再进行,但循环继续。

3、代码

//含重复元素的全排列
import java.util.Scanner;
public class repeatperm {
   public static void main(String []args)
   {
        String m=new Scanner(System.in).nextLine();
        String []numbers=m.split("\\s+");
        
        int x[]=new int[numbers.length+1];
        for(int i=0;i<numbers.length;i++)
            x[i+1]=Integer.parseInt(numbers[i]);
        
        perm(x,1);
   } 
   //全排列
   public static void perm(int[] x,int t)
   {
        int n=x.length-1;
        
        if(t>n)
        {
            for(int i=1;i<n+1;i++)
                System.out.print(x[i]+" ");
            System.out.println();
        }
        else
        {
            for(int i=t;i<n+1;i++)
            {
                //约束条件,保证不再重复
                if(x[t]==x[i]&&t!=i)
                    continue;
                swap(t,i,x);
                perm(x,t+1);
                swap(t,i,x);
            }
        }
   }
   public static void swap(int t,int i,int []x)
   {
        int tmp=x[i];
        x[i]=x[t];
        x[t]=tmp;
   }
}

三、 组合

1、概述

        输入n和k,从1~n中任意不放回抽取k个值的所有情况,输入n=4,k=2,输出【1,2】,【1,3】,【1,4】,【2,3】,【2,4】,【3,4】。

2、算法

        子集树,在叶子结点未遍历结束前,每一层的值都为上一层的节点值到n之间所有的遍历。

3、代码

//组合问题
import java.util.Scanner;
public class combination {
    public static void main(String[] args)
    {
        int n=new Scanner(System.in).nextInt();  //n=4
        int k=new Scanner(System.in).nextInt();  //k=2
        int x[]=new int [k+1];
        combine(n,k,1,x);
    }
    public static void combine(int n,int k,int t,int x[])
    {
        if(t>k)
        {
            for(int i=1;i<=k;i++)
                System.out.print(x[i]+" ");
            System.out.println();
        }
        else
        {
            for(int i=x[t-1]+1;i<=n;i++)
            {
                x[t]=i;
                combine(n,k,t+1,x);
            }
        }
    }
}

四、组合总和

1、概述

        输入n和k,输出1-9的任取k个数的组合中,组合加和等于n的所有可能情况。

2、算法

        子集树算法,与上一道题相同,只需要在输出的时候,添加限制总和等于n的输出。另外可以进行改进,对于问题规模过大的情况,如果未完成的组合,组合总和已经大于等于n,则进行剪枝。

3、代码

//组合总和
import java.util.Scanner;
public class combinationsum {
   public static void main(String[] args)
    {
        int n=new Scanner(System.in).nextInt();  //n=7,判断条件和
        int k=new Scanner(System.in).nextInt();  //k=3
        int x[]=new int [k+1];
        combine(n,k,1,x);
    }
    public static void combine(int n,int k,int t,int x[])
    {
        if(t>k)
        {
            int sum=0;
            for(int j:x)
                sum+=j;
            if(sum==n)
            {
                for(int i=1;i<=k;i++)
                    System.out.print(x[i]+" ");
                System.out.println();
            }
        }
        else
        {
            for(int i=x[t-1]+1;i<=9;i++)
            {
                x[t]=i;
                combine(n,k,t+1,x);
            }
        }
    } 
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1224251.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

口袋参谋:一键下载任意买家秀图片、视频,是怎么做到的!

​对于淘宝商家来说&#xff0c;淘宝买家秀是非常的重要的。买家秀特别好看的话&#xff0c;对于提升商品的销量来说&#xff0c;会有一定的帮助&#xff0c;如何下载别人的买家秀图片&#xff0c;然后用到自己的店铺中呢&#xff1f; 这里我可以教叫你们一个办法&#xff01;那…

ROS基础—关于参数服务器的操作

1、rosparam list 获取参数服务器的所有参数。 2、rosparam get /run_id 获取参数的值

【uniapp】使用扫码插件,解决uni.scanCode扫码效率低的问题

1. 背景 uniapp 中自带的二维码扫描的 API 是 uni.scanCode&#xff0c;但有如下问题&#xff1a; 二维码扫描的效率不高&#xff0c;有些需要扫2秒左右 较小或模糊的一些二维码无法识别出来&#xff0c;多次扫同样的一个码可能出现扫码失败的情况 受环境影响大&#xff0c…

腾讯云服务器怎么买便宜?腾讯云服务器新人专享限时特惠购买链接

腾讯云作为国内领先的云计算服务提供商之一&#xff0c;为个人用户和企业用户提供了多种优惠活动。这些活动不仅能帮助用户节省成本&#xff0c;还能提升企业的效益。本文将介绍腾讯云的多重优惠活动&#xff0c;让用户能够以更优惠的价格购买和续费云服务器。 腾讯云双十一领…

动手学深度学习——循环神经网络的简洁实现(代码详解)

文章目录 循环神经网络的简洁实现1. 定义模型2. 训练与预测 循环神经网络的简洁实现 # 使用深度学习框架的高级API提供的函数更有效地实现相同的语言模型 import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2lbatch_size, …

解决docker运行elastic服务端启动不成功

现象&#xff1a; 然后查看docker日志&#xff0c;发现有vm.max_map_count报错 ERROR: [1] bootstrap checks failed [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] 解决办法&#xff1a; 1. 宿主机&#xff08;运行doc…

【springboot笔记】程序可用性检测ApplicationAvailability

1.背景 springboot-3.1.5 ApplicationAvailability LivenessState ReadinessState AvailabilityChangeEvent 我们可以通过ApplicationAvailability获取当前应用程序的可用性&#xff0c;这个可用性包括ApplicationContext和对外请求路由两种。 LivenessState 是表示Applicatio…

【C++】类与对象 II 【深入浅出 万字详解】

类与对象 II 一、类的6个默认成员函数二、构造函数前言&#xff1a;构造函数产生的由来 及引入C语言中关于初始化会出现的问题总结&#xff1a;&#xff08;一&#xff09;构造函数的 概念&#xff08;二&#xff09;构造函数的 特性★ 构造函数 和 函数声明 的区分 三、析构函…

数学建模 | 灰色预测原理及python实现

目录 一、灰色预测的原理 二、灰色预测的应用及python实现 一、灰色预测的原理 灰色预测是以灰色模型为基础&#xff0c;灰色模型GM(n,h)是微分方程模型&#xff0c;可用于描述对象做长期、连续、动态的反应。其中&#xff0c;n代表微分方程式的阶数&#xff0c;h代表微分方…

下一代搜索引擎会什么?

现在是北京时间2023年11月18日。聊一聊搜索。 说到搜索&#xff0c;大家首先想到的肯定是谷歌&#xff0c;百度。我把这些定义成上一个时代的搜索引擎。ChatGPT已经火热了有一年的时间了&#xff0c;大家都认为Ai搜索是下一代的搜索。但是AI搜索&#xff0c;需要的是很大算力&a…

【动态规划】求解编辑距离问题

目录 问题描述递推关系运行实例时空复杂度优化Hirschberg 算法 问题描述 编辑距离问题是求解将⼀个字符串转换为另⼀个字符串所需的插⼊、删除、替换的最小次数。 C O M M O M → s u b C O M M U M → s u b C O M M U N → i n s C O M M U N E \mathbb{COMMOM} \overset{sub…

迪杰斯特拉算法(C++)

目录 介绍&#xff1a; 代码&#xff1a; 结果&#xff1a; 介绍&#xff1a; 迪杰斯特拉算法&#xff08;Dijkstras algorithm&#xff09;是一种用于计算加权图的单点最短路径的算法。它是由荷兰计算机科学家Edsger W. Dijkstra在1956年发明的。 该算法的思路是&#xf…

Confluence 快速安装教程

安装jdk yum install -y java-1.8.0-openjdk.x86_64 java -version 安装MySQL mkdir -p /data/mysql/data chmod 777 /data/mysql/datadocker rm -f mysql docker run -d --name mysql \-p 3306:3306 \-e MYSQL_ROOT_PASSWORDfingard1 \-v /data/mysql/data:/var/lib/mysql …

使用Pandas进行时间重采样,充分挖掘数据价值

大家好&#xff0c;时间序列数据蕴含着很大价值&#xff0c;通过重采样技术可以提升原始数据的表现形式。本文将介绍数据重采样方法和工具&#xff0c;提升数据可视化技巧。 在进行时间数据可视化时&#xff0c;数据重采样是至关重要且非常有用的&#xff0c;它支持控制数据的…

SQL 文本函数

前言 SQL文本函数是SQL语言中非常有用的一类函数&#xff0c;它们用于处理和操作字符串数据。在实际应用中&#xff0c;我们经常需要对数据库中的文本数据进行各种操作&#xff0c;比如提取子串、替换子串、拼接字符串等等。而SQL文本函数可以帮助我们轻松地完成这些任务&#…

SQL SERVER 2008安装教程

SQL SERVER 2008安装教程 本篇文章介绍了安装SQL Server 2008企业版的软硬件配置要求&#xff0c;安装过程的详细步骤&#xff0c;以及需要注意的事项。 安装步骤 (1). 在安装文件setup.exe上&#xff0c;单击鼠标右键选择“以管理员的身份运行”&#xff0c;如下图所示&#…

一文搞懂设计模式之代理模式

大家好&#xff0c;我是晴天&#xff0c;本周我们又见面了。本周有点发烧感冒&#xff0c;更文有点慢了&#xff0c;请大家见谅。言归正传&#xff0c;本周我们继续一起学习一文搞懂设计模式系列文章之代理模式。 什么是代理模式 我们先来看看 GoF 对代理模式的定义&#xff1…

HarmonyOS真机调试报错:INSTALL_PARSE_FAILED_USESDK_ERROR处理

1、 新建应用时选择与自己真机匹配的sdk版本 查看自己设备sdk版本 创建时先择匹配版本&#xff1a; 2、 根据报错提示连接打开处理方案 3、查询真机版本对应的compileSdkVersion 和 compatibleSdkVersion 提示3.1版本之后和3.1版本之前的不同命令&#xff08;此处为3.0版…

Git企业开发级讲解(四)

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、理解分⽀二、创建分支三、切换分⽀四、合并分⽀五、删除分⽀六、合并冲突七、分⽀管理策略…

轻量封装WebGPU渲染系统示例<34>-数据驱动之Json构建场景

场景和数据之间的互通&#xff1a; 场景数据化或者数据化场景&#xff0c;是当前的主流场景数据构成方式。方便传输方便交换甚至是交互。 内置数据互通机制更有利于用户在各种应用场合下实现具体的3D相关的应用需求。用户只需要关心标准的或者约定好的数据定义及操作方式就能方…