热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

生成全排列格雷码邮票问题(回溯)

参考视频bilibilfjnuzs文章目录一、全排列1.题目分析2.伪代码二、格雷码三、邮票问题一、全排列1.题目分析大概意思就是给你一堆数字,把他们的全排列输出

参考视频bilibil fjnuzs

文章目录

  • 一、全排列
    • 1.题目分析
    • 2.伪代码
  • 二、格雷码
  • 三、邮票问题




一、全排列

1.题目分析

大概意思就是给你一堆数字,把他们的全排列输出来。不要保存,直接就是一棵多分枝的树,每一层每一层走下去,到了树叶的时候输出,再返回到上一层去其他分支。也可理解为递归的时候,上一层(数组前面部分)都固定了,当前这层你把每个数都试了一遍。

2.伪代码

代码如下(示例):

设一共有n层,目前在t层,A数组去记录当前排列
fun(t)if(t&#61;n)print(A)elsefor 每个数字都遍历一遍A[t] <-> A[i]fun(t&#43;1)A[i]<->A[t]

举个例子&#xff0c;输入1234567
假设在2这一层了&#xff0c;那么2这个位置的和134567都换了一遍。假设某一次&#xff0c;它被换成某一个数比如4时&#xff0c;前面就确定了14&#xff0c;3又开始和142567换……递归下去。

然后我们讨论一下为什么要换回来&#xff0c;有点类似于回到树的上一层&#xff0c;简单来说如果不换回来会出现相同的排列的数。当他到了第7层输出了之后&#xff0c;假设输出7654321&#xff0c;换回来是在1654327&#xff0c;接下来时7和65432分别换了。不换的话继续循环&#xff0c;是1可以和65432换&#xff0c;是很不一样的。

二、格雷码

对于给定的正整数n&#xff0c;格雷码为满足如下条件的一个编码序列&#xff1a;
(1) 序列由2n个编码组成&#xff0c;每个编码都是长度为n的二进制位串。
(2) 序列中无相同的编码。
(3) 序列中位置相邻的两个编码恰有一位不同。
例如&#xff1a;n&#61;2时的格雷码为&#xff1a;{00, 01, 11, 10}。
思路&#xff1a;和全排列是一个道理。用树结构存储每一个01结点&#xff0c;可以得到一棵完全二叉树&#xff0c;这样就能用数组存储这棵树。为了使序列中位置相邻的两个编码恰有一位不同&#xff0c;一棵树子节点01则旁边一个为10。采用先序遍历&#xff0c;保留父节点&#xff0c;每到一个子节点就能输出一个格雷码。

在这里插入图片描述通过0110重复的规律还能对二叉树进行裁枝&#xff0c;从下标为6开始&#xff0c;将下标对4求余后能得到正确的元素。

import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner input &#61; new Scanner(System.in);int times &#61; input.nextInt();for(int k&#61;0; k<times; k&#43;&#43;) {int num &#61; input.nextInt();ArrTree t &#61; new ArrTree(num);t.order();}}
}class ArrTree{private int[] tree &#61; {2,0,1, 0,1,1,0};private int[] arr;private int num;private int len;public ArrTree(int num) {this.num &#61; num;this.len &#61; (int) Math.pow(2,num&#43;1)-2;this.arr &#61; new int[num];}public void print(int[] arr) {for(int i&#61;0; i<arr.length; i&#43;&#43;) {System.out.printf("%d ",arr[i]);}System.out.print("\n");}public void order() {//index &#61; 1树的下标//i &#61; 0存当前二进制数的数组下标order(0, 1);order(0, 2);}public void order(int i, int index) {if(index > 6) {arr[i] &#61; tree[(index-7)%4&#43;3];}else {arr[i] &#61; tree[index];}if(i &#61;&#61; num-1) {print(arr);return;}//左递归if((index*2&#43;1) < len) {order(i&#43;1, index*2&#43;1);}//右递归if((index*2&#43;2) <&#61; len) {order(i&#43;1, index*2&#43;2);}}
}

三、邮票问题

设有n种不同面值a1, a2,…, an的邮票&#xff0c;规定每封信最多贴m张邮票。对于给定的m&#xff0c;n&#xff0c;求出最大的邮资连续区间。例如&#xff0c;给定n&#61;3&#xff0c;m&#61;3&#xff0c;邮票面值分别为2, 3, 5&#xff0c;则最大的邮资连续区间为[2&#xff0c;13]。
输入&#xff1a;输入的第一行是一个正整数n&#xff0c;表示测试例个数。接下来几行是n个测试例的数据&#xff0c;每个测试例的数据由两行组成&#xff0c;其中第一行含两个正整数n和m (1<&#61;n, m<&#61;10)&#xff0c;表示有n种邮票&#xff0c;每封信最多贴m张邮票&#xff1b;第二行含n个正整数&#xff0c;表示n种邮票的面值。同一行整数之间用一个空格隔开。
思路&#xff1a;采用深度优先遍历&#xff0c;不贴邮票表示为0&#xff0c;这样每一层可以循环四次&#xff0c;每次循环到了最后一层就去记录这个数。记录方式是&#xff0c;以全部贴最大面值时的值为一个数组最后一个元素下标&#xff1b;当找到对应下标&#xff0c;就把这个元素置为1。最后将这个数组遍历一次记录连续为1的长度和起始下标。

import java.util.Arrays;
import java.util.Scanner;public class Stamp {static int n;static int m;static int[] tree;//static int count &#61; 0;public static void main(String[] args) {Scanner in &#61; new Scanner(System.in);int times &#61; in.nextInt(); //测试次数for(int t&#61;0; t<times; t&#43;&#43;) {n &#61; in.nextInt(); //n种邮票m &#61; in.nextInt(); //最多贴m张tree &#61; new int[n&#43;1];tree[0] &#61; 0; //不贴上去for(int i&#61;1; i<n&#43;1; i&#43;&#43;) {tree[i] &#61; in.nextInt();}System.out.println(Arrays.toString(tree));int[] value &#61; new int[tree[n]*m&#43;1];dfs(1, 0, value);System.out.println(Arrays.toString(value));Search(value);}}public static void dfs(int t, int sum, int[] res) {for(int i&#61;0; i<&#61;n; i&#43;&#43;) {sum &#43;&#61; tree[i];if(t &#61;&#61; m) {res[sum] &#61; 1;sum -&#61; tree[i];}else {dfs(t&#43;1, sum, res);sum -&#61; tree[i];}}}public static void Search(int[] a) {int lastLen &#61; 1;int lastIndex &#61; 1;int thisLen &#61; 0;int thisIndex &#61; 1;boolean flag &#61; true;for(int i&#61;1; i<a.length; i&#43;&#43;) {//把0屏蔽掉if(a[i] &#61;&#61; 1) {//连续相加&#43;&#43;thisLen;if(flag) {thisIndex &#61; i;flag &#61; false;}}else {//断开记录if(lastLen < thisLen) {lastLen &#61; thisLen;lastIndex &#61; thisIndex;flag &#61; true;thisLen &#61; 0;}}}System.out.printf("%d %d", lastIndex, lastIndex&#43;lastLen-1);}
}


推荐阅读
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • Ihavethefollowingonhtml我在html上有以下内容<html><head><scriptsrc..3003_Tes ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • 学习Java异常处理之throws之抛出并捕获异常(9)
    任务描述本关任务:在main方法之外创建任意一个方法接收给定的两个字符串,把第二个字符串的长度减1生成一个整数值,输出第一个字符串长度是 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了如何在wxpython中将matplotlib图表嵌入到自定义窗体中的方法。通过调用FigureCanvasWx类,可以实现在自定义窗体中显示matplotlib图表。同时,还介绍了与此相关的一些类和参数。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
author-avatar
tomodachitch
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有