模拟-bailian1833:排列(代码片段)

zhangyue123 zhangyue123     2023-04-03     117

关键词:

题目描述

总时间限制: 5000ms 内存限制: 65536kB
描述
题目描述:
大家知道,给出正整数n,则1到n这n个数可以构成n!种排列,把这些排列按照从小到大的顺序(字典顺序)列出,如n=3时,列出1 2 3,1 3 2,2 1 3,2 3 1,3 1 2,3 2 1六个排列。

任务描述:
给出某个排列,求出这个排列的下k个排列,如果遇到最后一个排列,则下1排列为第1个排列,即排列1 2 3…n。
比如:n = 3,k=2 给出排列2 3 1,则它的下1个排列为3 1 2,下2个排列为3 2 1,因此答案为3 2 1。
输入
第一行是一个正整数m,表示测试数据的个数,下面是m组测试数据,每组测试数据第一行是2个正整数n( 1 <= n < 1024 )和k(1<=k<=64),第二行有n个正整数,是1,2 … n的一个排列。
输出
对于每组输入数据,输出一行,n个数,中间用空格隔开,表示输入排列的下k个排列。
样例输入
3
3 1
2 3 1
3 1
3 2 1
10 2
1 2 3 4 5 6 7 8 9 10
样例输出
3 1 2
1 2 3
1 2 3 4 5 6 7 9 8 10
来源
qinlu@POJ

解题分析

问题可以转化为求一个排列的下一个排列,在stl中有现成的算法 next_permulation(),在这里我们考虑自己实现一下next_permulation。
因为一个数集的全排列需要按照字典序升序排列,这就要求两个相邻的排列之间前缀尽可能重合度高,那么可以采用这种策略:
1.从最后一个数xn开始向左查找,一直找到某个位置j,使 x[j] > x[j-1],这么做的原因是,在x[j..n]是降序排列,那么在这段子序列是它全排列中最大的。
2.从x[j..n]中寻找比x[j-1]大的数 a,要刚刚好大,然后x[j-1]与这个数交换,因为a是第一个比x[j-1]大的数,所以交换后x[j..n]仍然保持降序
3.最后将x[j..n] reverse一下就可以

解题代码

#include <cstdio>
#include <algorithm>

using namespace std;
int a[1025];

void next_permutation(int length)
    int j = length - 1;
    while(j > 0 && a[j - 1] > a[j])
        j -- ;
    
    if(j == 0)
        for(int i = 0; i < length; i++)
            a[i] = i + 1;
        
        return;
    
    int i;
    for( i = length - 1; i >= j; i--)
        if(a[i] > a[j - 1])
            int temp = a[i];
            a[i] = a[j - 1];
            a[j - 1] = temp;
            break;
        
    
    i = length - 1;
    while(j < i)
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
        j++; i--;
    


int main()
    int t;
    scanf("%d", &t);
    int n, k;
    while(t--)
        memset(a, 0, sizeof(a));
        scanf("%d%d", &n, &k);
        for(int i = 0; i < n; i++)
            scanf("%d", a + i);
        for(int i = 0; i < k; i++)
            next_permutation(n);
        for(int i = 0; i < n - 1; i++)
            printf("%d ", a[i]);
        printf("%d
", a[n - 1]);
    
    return 0;

bailian1835poj1835宇航员模拟(代码片段)

宇航员TimeLimit:2000MSMemoryLimit:30000KTotalSubmissions:8900Accepted:3629Description问题描述:  宇航员在太空中迷失了方向,在他的起始位置现在建立一个虚拟xyz坐标系,称为绝对坐标系,宇航员正面的方向为x轴正方向,... 查看详情

poj1833生成排列

题目链接:POJ1833/*************************************author:GrantYuan*time:2014/10/1916:38*source:POJ1833*algorithm:STL+排列的生成*************************************/#include<iostream>#include<algo 查看详情

bailian4118开餐馆dp(代码片段)

4118:开餐馆总时间限制:1000ms内存限制:65536kB描述北大信息学院的同学小明毕业之后打算创业开餐馆.现在共有n个地点可供选择。小明打算从中选择合适的位置开设一些餐馆。这n个地点排列在同一条直线上。我们用一个整数序列m1,m... 查看详情

poj1833排列stl/next_permutation

...bsp;大家知道,给出正整数n,则1到n这n个数可以构成n!种排列,把这些排列按照从小到大的顺序(字典顺序)列出,如n=3时,列出123,132,213,231,312,321六个排列。 任务描述: 给出某个排列,求出这个排列的下k个排... 查看详情

bailian2746约瑟夫问题(代码片段)

...即最后猴王的编号样例输入621248300样例输出517问题链接:Bailian2746约瑟夫问题问题简述:(略)问题分析:????约瑟夫问题有2种解法,一是模拟法,二是数学法。????数学法需要数学推导,这里略去推导过程,只给出程序。????模... 查看详情

bzoj1833数字计数(代码片段)

题目链接找$[1$~$a-1]$和$[1$~$b]$中各数码出现的次数之后相减就是答案上代码:/**************************************************************Problem:1833User:zhangheranLanguage:C++Result:AcceptedTime:0msMemory:1292kb*************** 查看详情

错误代码1833cannotchangecolumnusedinaforeign(代码片段)

最近修改mysql数据库表中的字段长度时报错,执行更改的sql语句:ALTERTABLEserver_listMODIFYCOLUMNserver_lipCHAR(25);报错信息:1queriesexecuted,0success,1errors,0warnings查询:altertableserver_listmodifycolumnserver_lipchar(25)错误代码:1833Can 查看详情

bzoj1833数位dp(代码片段)

很裸的数位dp。#include<bits/stdc++.h>#defineLLlonglong#definefifirst#definesesecond#definemkmake_pair#definePIIpair<int,int>#definey1skldjfskldjg#definey2skldfjsklejgusingnamespacestd;constintN= 查看详情

441.排列硬币模拟(代码片段)

https://leetcode-cn.com/problems/arranging-coins/classSolutionpublic:intarrangeCoins(intn)intcnt=0,i=1;while(n>=i)cnt++,n-=i,i++;returncnt;; 查看详情

bailian2975caesarcryptogram(代码片段)

2975:CaesarCryptogram描述JuliusCaesarinventesacryptogramthatconvertsastringtoanotherstring.Theruleisthateveryletterinanoriginalstringshouldbereplacedbytheletterwhichtakesthefifthplaceafteritinthealphabe 查看详情

codeforcesgoodbye2017b.newyearandbuggybot枚举全排列模拟(代码片段)

B.NewYearandBuggyBottimelimitpertest1secondmemorylimitpertest256megabytesinputstandardinputoutputstandardoutputBobprogrammedarobottonavigatethrougha2dmaze.Themazehassomeobstacles.Emptycellsaredenotedb 查看详情

bzoj1833数字计数(代码片段)

题目大意:给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次思路:不知道黄学长他们的dp都是怎么dp的搞神的方法太强啦%%%数位乱搞。。推了公式,然后每一位直接套用公式每一位分3种情况小于该... 查看详情

bailian2796bailian3681数字求和序列处理(代码片段)

2796:数字求和总时间限制:3000ms内存限制:65536kB描述给定一个正整数a,以及另外的5个正整数,问题是:这5个整数中,小于a的整数的和是多少?输入输入一行,只包括6个小于100的正整数,其中第一个正整... 查看详情

bailian2819w的密码密码+模拟(代码片段)

2819:W的密码总时间限制:1000ms内存限制:65536kB描述加密一条信息需要三个整数码,k1,k2和k3。字符[a-i]组成一组,[j-r]是第二组,其它所有字符([s-z]和下划线)组成第三组。在信息中属于每组的字符将被循环地向左移动ki个位置。每组中的... 查看详情

动态规划:熟练度练习(poj1458最佳加法表达式bailian2755poj3624bailian1088)(代码片段)

最长公共子序列Language:DefaultCommonSubsequenceTimeLimit:1000MSMemoryLimit:10000KTotalSubmissions:47599Accepted:19562DescriptionAsubsequenceofagivensequenceisthegivensequencewithsomeelements(possiblenone)lef 查看详情

[入门组模拟赛]幸运数与排列(代码片段)

题目描述一个数是幸运数当且仅当这个数仅由4和7构成,比如47,744,4747。   在1到n的全排列中字典序第k小的排列中,有多少个幸运数在排列中的位置编号也是幸运数。输入一行两个整数n,k。输出一个整数表示答案。如... 查看详情

数位dpbzoj1833:[zjoi2010]count数字计数(代码片段)

数位dp姿势一直很差啊;顺便庆祝一下1ADescription给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。Input输入文件中仅包含一行两个整数a、b,含义如上所述。Output输出文件中包含一行10个整数,分别... 查看详情

1833:[zjoi2010]count数字计数(代码片段)

题意:给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。 经历一中午,终于TM做出来了满满的成就。。。以f[i][j][k]代表长度为i最高位为j数码k出现几次 修正:1、预处理  若最高位j==k还... 查看详情