POJ 3785 The Next Permutation 全排列字典序法

给一个排列  求下一个排列 按字典序

跟普通排列不同的地方就是 有相同的数字

那么就把普通的一改就完事

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <cmath>
#include <algorithm>
#include <map>
#include <ctime>
#define MAXN 222
#define MAXM 6122222
#define INF 1000000001
using namespace std;
int n, c[1111];
char s[1111];
void get_next() {

    int pos1 = n - 1;
    while(pos1 > 0 && c[pos1] >= c[pos1 + 1]) pos1--;  //>变成了>=
    int pos2 = n;
    while(c[pos2] <= c[pos1]) pos2--; //<变成了<=
    swap(c[pos2], c[pos1]);
    int l = pos1 + 1, r = n;
    while(l < r) {
        swap(c[l], c[r]);
        l++; r--;
    }
}
int main() {
    int T, cas;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &cas);
        scanf("%s", s);
        n = strlen(s);
        for(int i = 0; i < n; i++) {
            c[i + 1] = s[i] - '0';
        }
        printf("%d ", cas);
        bool flag = 1;
        for(int i = 1; i < n; i++)
            if(c[i] < c[i + 1]) flag = 0;
        if(flag) {
            printf("BIGGEST\n");
            continue;
        }
        get_next();
        for(int i = 1; i <= n; i++) printf("%d", c[i]);
        printf("\n");
    }
    return 0;
}
时间: 2024-08-10 00:07:06

POJ 3785 The Next Permutation 全排列字典序法的相关文章

字典序法生成全排列算法的证明

引言 对一个给定数据进行全排列,在各种场合经常会用到.组合数学中,生成全排列的方法有很多,卢开澄老师的<组合数学>中就介绍了三种:序数法,字典序法,临位互换法等.其中以字典序法由于算法简单,并且使用的时候可以依照当前状态获取下一个状态,直到所有排列全部完成,方便在程序中随要随用,应用比较广泛,STL中的Next_permutation也是使用此法. 算法定义 首先看什么叫字典序,顾名思义就是按照字典的顺序(a-z, 1-9).以字典序为基础,我们可以得出任意两个数字串的大小.比如 "

[全排列]基于逆序列的字典序法的改进

摘要: 字典序法是生成全排列的经典算法.本文在对字典序法进行分析的基础上,提出了一种基于逆序列的改进字典序全排列生成算法.通过与传统的四种全排列生成算法进行对比,本文方法可以大大提高全排列的生成效率.关键词:全排列;字典序;逆序列 基于逆序列的字典序法的改进 code

全排列算法分析(原创方法/一般方法/字典序法)

全排列算法即对给定的一个序列,输出其所有不同的(n!种)排列,例如: 给定序列{1, 2, 3}有{1, 2, 3}.{1, 3, 2}.{2, 1, 3}.{2, 3, 1}.{3, 1, 2}.{3, 2, 1}这6种排列 好像很容易就能写出来,对于更长的序列也只是时间问题,最终肯定能够用笔一一列出来 但是要用程序实现的话,可能让人有点无从下手(乍看好像很简单),下面给出三种不同的解全排列的方法: ------- 一.原创方法 所谓的原创方法就是不考虑算法的效率及其他因素,完全为了解决问题而

全排列算法(字典序法、SJT Algorithm 、Heap&#39;s Algorithm)

一.字典序法 1) 从序列P的右端开始向左扫描,直至找到第一个比其右边数字小的数字,即. 2) 从右边找出所有比大的数中最小的数字,即. 3) 交换与. 4) 将右边的序列翻转,即可得到字典序的下一个排列. 5) 重复上面的步骤,直至得到字典序最大的排列,即左边数字比右边的大的降序排列. 二.SJT Algorithm 初始状态为. 1) 找到最大的可移动数m(当一个数指向一个比它小的数是,该数就是可移动数) 2) 交换m和m所指向的数 3) 改变所有比m大的数的方向 4) 重复上面的步骤,直至

[LeetCode] Permutations 排列生成算法之字典序法

字典序排序生成算法 字典序法就是按照字典排序的思想逐一产生所有排列. 例如,由1,2,3,4组成的所有排列,从小到大的依次为: 1234, 1243, 1324, 1342, 1423, 1432, 2134, 2143, 2314, 2341, 2413, 2431, 3124, 3142, 3214, 3241, 3412, 3421, 4123, 4132, 4213, 4231, 4312, 4321. 分析这种过程,看后一个排列与前一个排列之间有什么关系? 再如,设有排列(p)=276

PHP_字典序法获得排列组合

前段时间一次聚会闲聊时聊到一个问题,就是给你一排数组,例如1,2,3,4,5,如何能高效的获取上述数列的所有排列组合,正巧没事,研究了一下,一开始以为是个很简单的问题,就直接开始写代码了,后来发现怎么循环也不理想,基本上都有一些不必要的消耗,百度一下看到一个不错的算法,字典序法,顺便学习一下,然后记录之. 摘一段算法思想: 设P是[1,n]的一个全排列. P=P1P2-Pn=P1P2-Pj-1PjPj+1-Pk-1PkPk+1-Pn , j=max{i|Pi<Pi+1}, k=max{i|Pi>

字典序法生成全排列算法图

算法定义 首先看什么叫字典序,顾名思义就是按照字典的顺序(a-z, 1-9).以字典序为基础,我们可以得出任意两个数字串的大小.比如 "1" < "12"<"13". 就是按每个数字位逐个比较的结果.对于一个数字串,"123456789", 可以知道最小的串是 从小到大的有序串"123456789",而最大的串是从大到小的有序串"*987654321".这样对于"1

【LeetCode】Permutation全排列

1. Next Permutation 实现C++的std::next_permutation函数,重新排列范围内的元素,返回按照 字典序 排列的下一个值较大的组合.若其已经是最大排列,则返回最小排列,即按升序重新排列元素.不能分配额外的内存空间. void nextPermutation(vector<int>& nums) { next_permutation(nums.begin(), nums.end()); } 全排列 Permutation 问题已经被古人研究透了,参见 W

全排列 字典序全排列

全排列递归的方法参考 leetcode 47 字典序算法:升序 参考https://www.jianshu.com/p/58ae30cf6bca 实现: 判断了是否相等 计算全排列的数量方法为 n!/ (m!*p!*...)   m,p为重复的数字的重复量 参考 https://blog.csdn.net/sinat_36215255/article/details/78197129 #include<iostream> #include<algorithm> #include&l