排列——逆康托展开

2024-04-07 01:08
文章标签 展开 排列 逆康托

本文主要是介绍排列——逆康托展开,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Description

1,2,3,…n是自然数1到n的最小的排列,易知,第二小的排列是:1,2,3….n,n-1。现在给你2个值n和m,请找到1到n个数的第m小的排列。

Input

输入包括多组样例,对于每组样例包括两个整数n和m(1<=n<=1000,1<=m<=10000000),分别如题目所述

Output

输出第m小的排列的后各个数字,中间用空格分开,每一个样例占一行

Sample Input

6 4
11 8
Sample Output

1 2 3 5 6 4
1 2 3 4 5 6 7 9 8 11 10
有关逆康托展开我就不赘述了,博客很多。。。这题是我们学校的提,要加1的特判,因为有一个数据错的

#include<stdio.h>
#include<string.h>
int jc[2000];
void init()
{jc[1]=1;jc[0]=1;for(int i=2;i<=13;i++){jc[i]=jc[i-1]*i;}
}
int ans[2000],vis[1005];
int main()
{init();int n,m;while(scanf("%d%d",&n,&m)!=EOF){if(n==1){printf("1\n");continue;}memset(vis,0,sizeof(vis));memset(ans,0,sizeof(ans));int pos;m--;for(int i=1;i<=13;i++){if(jc[i]>m){pos=i;break;}}for(int i=1;i<=pos;i++){int ct=m/jc[pos-i];m=m-ct*jc[pos-i];int j;for(j=1;j<=n;j++){if(!vis[j]){if(ct==0)break;ct--;}}ans[i]=j;vis[j]=1;}for(int i=1;i<=n-pos;i++){printf("%d ",i);}for(int i=1;i<=pos;i++){printf("%d ",ans[i]+n-pos);}printf("\n");}return 0;
}

这篇关于排列——逆康托展开的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/881286

相关文章

PHP字符串全排列

方法一: $str = 'abc';$a =str_split($str);perm($a, 0, count($a)-1);function perm(&$ar, $k, $m) {if($k == $m){ echo join('',$ar), PHP_EOL;}else {for($i=$k; $i<=$m; $i++) {swap($ar[$k], $ar[$i]);perm($ar

回溯——9.全排列

力扣题目链接 给定一个 没有重复 数字的序列,返回其所有可能的全排列。 示例: 输入: [1,2,3]输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] 解题思路 问题建模:题目要求给出一个数组的所有排列组合,属于典型的全排列问题,这可以用回溯法来解决。回溯法通过递归的方式,依次将数组中的每个元素放入排列中,直到生成

代码随想录刷题day25丨491.递增子序列 ,46.全排列 ,47.全排列 II

代码随想录刷题day25丨491.递增子序列 ,46.全排列 ,47.全排列 II 1.题目 1.1递增子序列 题目链接:491. 非递减子序列 - 力扣(LeetCode) 视频讲解:回溯算法精讲,树层去重与树枝去重 | LeetCode:491.递增子序列_哔哩哔哩_bilibili 文档讲解:https://programmercarl.com/0491.%E9%80%92%E

python 实现第k个字典排列算法

第k个字典排列算法介绍 "第k个字典排列"算法通常指的是在给定的字符集合(例如,字符串中的字符)中,找到所有可能排列的第k个排列。这个问题可以通过多种方法解决,但一个常见且高效的方法是使用“下一个排列”算法的变种,或称为“第k个排列”的直接算法。 方法一:使用“下一个排列”的变种 生成所有排列:首先生成所有排列,但显然这种方法对于较大的输入集合是不切实际的,因为它涉及到大量的计算和存储。 排序

C++解决:求排列数

描述 输入两个整数m,n,求m个数字中选n个数的排列数。(1<=n<=m<=50) 输入描述 两个正整数m和n。 输出描述 一个正整数表示排列数。 用例输入 1  6 5 用例输出 1  720 AC code #include<bits/stdc++.h>using namespace std;int fun(int n) {int sum=1;for(int i=n

每日一题~cf 970 div3 (A思维,B小模拟,C二分,D排列数建图成环,E 26个字母暴力+前缀和,F 逆元,G 数论gcd )

A 题意: 有 a 个1 ,b 个2.问是否能将这些数划分为两个数值相等的集合。 输出 YES 或者 NO —————— 问题等价于 将数组 分成两个数值相同的数组。所以sum 应该是偶数。也就是说 1 的个数是偶数。在i1的个数是偶数的情况下,将 2 分成两份,如果2 的个数是偶数,OK。如果是奇数那么需要1来补齐,如果1 的个数大于等于2那么可以补齐。(1 的个数是偶数,需要2个1来补齐,剩下

Leetcode刷题笔记:全排列

这是一个经典的回溯问题,下面是一个C++版本的解法: class Solution {public:void backtrack(vector<vector<int>>& res, vector<int>& nums, int start) {// 如果start到达nums的末尾,说明已经生成一个完整的排列if (start == nums.size()) {res.push_back(

再谈全排列

题目链接: . - 力扣(LeetCode) 每次做全排列的题目,我都要孕育好一阵子,到底怎么去思考这个问题呢? 首先,我觉得最好的方式就是画个树。 画了树之后,你就知道,这个问题,是一个循环遍历的问题,但是再遍历的过程中,你需要基于过去的状态(哪些元素被存储了),改变你之后的行为。 此外。我们还需要考虑终止条件,然后,这是一个回溯的问题,那么你需要考虑的就是回溯之后需要怎样的

PCB过孔规则排列,还是随机?

在现代电子设备设计中,印刷电路板(PCB)的复杂性不断增加,尤其是在高密度集成电路和多层PCB中,过孔(Via)起到了至关重要的作用。过孔通过将PCB的不同层相互连接,使得电路板不再局限于平面的布线,而是实现了立体化的电气连接结构,从而提升了设计的灵活性和电气性能。 1. 过孔的定义与作用 过孔,顾名思义,是PCB板上的一种孔,用于连接PCB不同层之间的导电路径。由于单层PCB的布线空间有限

HTML 无序排列 有序排列 框架

HTML 无序排列  有序排列 : <html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title> 第四讲代码汇总</title></head><!--margin-left 对象左边外延边距 (margin-left:5px; 左边外延距离5px)margin-ri