下一个序列 题解

题目描述

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

	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\n", 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\n", k);
           continue;
       } else {
           printf("%d ", k);
           for (int i = 1; i <= n; i++) printf("%d", a[i]);
       }
       printf("\n");
   }
   return 0;
}
posted @ 2020-10-24 11:11  STrAduts  阅读(86)  评论(0编辑  收藏  举报