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

一、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);
            }
        }
    } 
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第12章 信息系统架构设计理论与实践&#xff08;P420~465&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

带您识别RJ45网口连接器/网口插座口的LED灯的平脚/斜脚,带弹/不带弹细节区分

Hqst华强盛&#xff08;盈盛电子&#xff09;导读&#xff1a;网口连接器,网口插座&#xff0c;也叫网口母座,因为产品规格众多&#xff0c;常常因为细小差别&#xff0c;耽误工程设计级或者生产排期延误&#xff0c;今天就带大家一起来认识下平脚RJ45网口连接器/网口插座与斜脚…

算法设计与分析 | 分治棋盘

题目 在一个2^k * 2^k个方格组成的棋盘中&#xff0c;恰有一个方格与其他方格不同&#xff0c;称该方格为一特殊方格&#xff0c;且称该棋盘为一特殊棋盘。在棋盘覆盖问题中&#xff0c;要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格&#xff0…

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

目录 问题描述递推关系运行实例时空复杂度优化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…

macbook ntfs能读不能复制 c盘ntfs拒绝访问怎么解决

如果你是一位Mac用户&#xff0c;你可能会遇到这样的问题&#xff1a;你的Mac能够读取NTFS格式的移动硬盘或U盘&#xff0c;但是不能往里面复制或者修改文件。或者&#xff0c;你的Windows电脑出现了C盘NTFS拒绝访问的错误&#xff0c;导致你无法正常使用系统。这些问题都是由于…

【vue2绘制echarts环状图】vue2使用echarts绘制环状图

效果图&#xff1a; 鼠标悬浮的效果图&#xff1a; 1&#xff1a;安装echarts yarn add echarts5.3.2 或 npm install echarts5.3.2 --save2.局部引入使用 在vue页面引入 <template><div><divref"myChart"style"{width: 400px;height: 350…

VMware Workstation Pro 12 ubuntu 20.04 突然奔溃,重新打开后导致win11系统蓝屏问题

1、虚拟机在执行一个程序时候&#xff0c;突然导致系统win11蓝屏 2、重新打开提示磁盘打开异常&#xff0c;网络搜索发现要删除磁盘lock文件&#xff0c;删除后&#xff0c;重启过程中还是会报各种异常 后来把所有的临时文件都删除了&#xff0c;就可以了 临时文件&#xff1…

如何去开发一个springboot starter

如何去开发一个springboot starter 我们在平时用 Java 开发的时候&#xff0c;在 pom.xml 文件中引入一个依赖就可以很方便的使用了&#xff0c;但是你们知道这是如何实现的吗。 现在我们就来解决这一个问题&#xff01; 创建 SpringBoot 项目 首先我们要做的就是把你想要给别…

wpf devexpress 开始点

此教程示范如何创建registration form和DevExpress WPF Data Editors 开始点 此项目源码 这个解决方案包含几个项目-每一个项目对应一个教程 RegistrationForm.BaseProject项目是基于工作的解决方案。项目包含三个视图&#xff1a;MainView&#xff0c;RegistraionView&…

Os-ByteSec

Os-ByteSec 一、主机发现和端口扫描 主机发现&#xff0c;靶机地址192.168.80.144 端口扫描&#xff0c;开放了80、139、445、2525端口 二、信息收集 访问80端口 路径扫描 dirsearch -u "http://192.168.80.144/" -e *访问扫描出来的路径&#xff0c;没有发现…

IO流-序列化流

一&#xff0c;序列化&#xff08;把java对象写到对象中去&#xff09; 二&#xff0c; Object OutputStream(对象字节输出流) 三&#xff0c;案例 package BigDecimal;import java.io.FileOutputStream; import java.io.ObjectOutputStream;public class Main {public static…

​软考-高级-系统架构设计师教程(清华第2版)【第14章 云原生架构设计理论与实践(P496~526)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第14章 云原生架构设计理论与实践&#xff08;P496~526&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

​软考-高级-系统架构设计师教程(清华第2版)【第13章 层次式架构设计理论与实践(P466~495)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第13章 层次式架构设计理论与实践&#xff08;P466~495&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

数据库的分库分表 详解

前言 一个系统随着用户量上升&#xff0c;产生的数据也越来越多&#xff0c;到达一定程度&#xff0c;数据库就会产生瓶颈。 首先单机数据库所能承载的连接数&#xff0c;io和吞吐量都是有限的&#xff0c;并发量上来数据库就渐渐顶不住了。 如果单表的数据量过大&#xff0…

阿里巴巴java开发手册-编程规约

编程规约 命名风格常量定义代码格式OOP 规约日期时间集合处理并发处理控制语句注释规约前后端规约其他 命名风格 【强制】代码中的命名均不能以下划线或美元符号开始&#xff0c;也不能以下划线或美元符号结束。 反例&#xff1a;_name / name / n a m e / n a m e / n a m e…

腾讯云服务器租用价格,腾讯云服务器价格流量怎么算?

首先&#xff0c;让我们来看看腾讯云服务器租用价格。根据您的需求不同&#xff0c;腾讯云提供了多种不同的配置选项&#xff0c;从轻量级应用服务器到高性能的GPU服务器&#xff0c;都可以满足您的需求。以下是一些常见的腾讯云服务器租用价格&#xff1a; 一、腾讯云服务器租…

vs2017 编译Qt 5.11.2 源码

SDK 10.0.22000.194 有 2种编译方式 &#xff0c;第二种 看下面 方式一: 1、问题描述&#xff1a; 使用VS编译程序时&#xff0c;运行库选择多线程&#xff08;/MT&#xff09;&#xff0c;表示采用多线程静态release的方式进行编译。 但是&#xff0c;发现编译是不能通过的…

使用 Filebeat+Easysearch+Console 打造日志管理平台

近年来&#xff0c;日志管理平台越来越流行。使用日志管理平台可以实时地、统一地、方便地管理和查看日志&#xff0c;挖掘日志数据价值&#xff0c;驱动运维、运营&#xff0c;提升服务管理效率。 方案架构 Beats 是轻量级采集器&#xff0c;包括 Filebeat、Metricbeat 等。E…

记一次服务器配置文件获取OSS

一、漏洞原因 由于网站登录口未做双因子校验,导致可以通过暴力破解获取管理员账号,成功进入系统;未对上传的格式和内容进行校验,可以任意文件上传获取服务器权限;由于服务器上配置信息,可以进一步获取数据库权限和OSS管理权限。二、漏洞成果 弱口令获取网站的管理员权限通…

资产设备管理系统

dtAsset 是一个固定资产设备管理系统&#xff0c;它专为中小企业的需求而设计。该软件提供了对常用资产设备进行信息化管理的功能&#xff0c;并支持自定义设备类型、导入导出数据、维护工作统计、采购管理、文档管理、运维监控 (使用 Zabbix)、知识库等功能。 主要模块 1.系统…