zoukankan      html  css  js  c++  java
  • 下一个序列 题解

    题目描述

    对于这个问题,你要写一个程序,这个程序读入一个大于零的十进制的数字(这个数字可能非常的大),输出下一个比它大的一个序列(原数字各个位上的数字重新排列的序列,同样也是十进制),例如:

    	123->132    279134399742->279134423799
    

    有可能存在某数字不存在这样的下一个序列,例如:

    	987
    

    输入格式

    第一行有一个整数P,表示接下来有P组数据。
    接下来有P行,每一行有两个整数。
    第一个整数表示数据的编号(1,2,3,...,P),第二个整数表示读入的十进制数字。

    输出格式

    每组测试数据输出两个整数。
    第一个整数表示数据的编号(1,2,3,...,P)。
    第二个整数表示下一个比它大的序列。如果该组测试数据不存在下一个比它大的序列,输出BIGGEST。

    样例输入

    3    
    1 123    
    2 279134399742    
    3 987
    

    样例输出

    1 132     
    2 279134423799     
    3 BIGGEST
    

    数据范围:

    1≤P≤1000,
    读入十进制数字的长度小于等于80

    分析

    毫无疑问,这是一道贪心题
    先不管大佬的操作,我们来分析一下:


    STEP1:

    在什么情况下,要输出BIGGEST?也就是目前这个序列在他的全排列中最大,是什么呢?拿 123 举个栗子
    它的全排列如下
    123 132 213 231 321 312不难看出,当这个序列是递减时,它一定是最大的,没看懂的找胡帅。另外,当序列长度为1时,也应该输出BIGGEST


    STEP2:

    如果不满足上面的情况,则意味着我们该推导此题的正解了
    首先,如果这个序列的前一部分为递减,则这一部分不能再改大了。所以,我们要枚举到第一个不符合递减的位置,找到后再把后面一部分改大一丢丢
    【找到这个位置后,在它后面找到最小的大于它的,交换。然后,再将后面那部分排序】

    STEP3

    LJS大佬提议叫我模拟一遍,我们再来举个栗子

    65816525125971
    

    首先,我们还是先排除一开始递减的部分,将后面半截拎出来

    816525125971
    

    在 8 后面找到最小的个大于它的,交换

    916525125871
    

    排序后

    911122555678
    

    所以答案就是

    65911122555678
    

    简单吗【???】
    AC代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int MAXN = 1005;
    int a[MAXN];
    char s[MAXN];
    
    int main() {
       int t;
       scanf("%d", &t);
       while (t--) {
           int k;
           scanf("%d %s", &k, s + 1);
           int n = strlen(s + 1);
           for (int i = 1; i <= n; i++) a[i] = s[i] - '0';
           if (n == 1) {
               printf("%d BIGGEST
    ", k);
               continue;
           }
           bool flag = false;
           for (int i = n - 1; i >= 1; i--) {
               if (a[i] < a[i + 1]) {
                   flag = true;
                   int v = 1, mi = 10;
                   for (int j = i + 1; j <= n; j++) {
                       if (a[i] < a[j] && a[j] < mi) {
                           mi = a[j];
                           v = j;
                       }
                   }
                   swap(a[i], a[v]);
                   sort(a + i + 1, a + n + 1);
                   break;
               }
           }
           if (flag == false) {
               printf("%d BIGGEST
    ", k);
               continue;
           } else {
               printf("%d ", k);
               for (int i = 1; i <= n; i++) printf("%d", a[i]);
           }
           printf("
    ");
       }
       return 0;
    }
    
  • 相关阅读:
    【convertio.co】免费在线文档转化神器
    成长需熬过“四苦”
    岁月饶过谁
    致我的未来
    一定要相信自己
    奋斗的意义是什么?
    一生一世一双人,半醉半醒半浮生
    逆境中的自己
    怎样才能让人看到你呢
    2020 遇见更好的自己
  • 原文地址:https://www.cnblogs.com/Chain-Forward-Star/p/13868060.html
Copyright © 2011-2022 走看看