1 条题解

  • 0
    @ 2025-4-28 20:58:15

    以下是针对这道题的题解:

    题目分析

    1. 目标:对于给定的由小写字母组成的字符串(识别码),如果存在后继识别码,则输出后继识别码;如果给定的识别码是该组字符序列中的最后一个,则输出 “No Successor”。
    2. 输入数据
      • 输入由一系列行组成,每行包含一个表示识别码的字符串。
      • 整个文件将由一行仅包含单个 # 的行来终止。
    3. 输出数据
      • 对于读取的每个识别码,输出包含一行,该行包含后继识别码或 “No Successor” 字样。
    4. 规则
      • 识别码由最多50个小写字母组成,可能包含重复字符。
      • 后继识别码是在给定字符集的所有可能排列中,按字母顺序排在当前识别码之后的下一个识别码。

    解题思路

    1. 读取输入
      • 使用 fgets 函数读取输入的每一行字符串,并去除行末的换行符。
      • 如果读取到的字符串为 #,则终止程序。
    2. 判断是否存在后继识别码
      • 从字符串的末尾开始向前遍历,找到第一个顺序对 (s[i - 1], s[i]),使得 s[i - 1] < s[i]。如果不存在这样的顺序对,则说明当前识别码是该组字符序列中的最后一个,输出 “No Successor”。
    3. 找到后继识别码
      • 从找到的位置 i 开始,在字符串的剩余部分中找到大于 s[i - 1] 且最小的字符 s[k]
      • 交换 s[i - 1]s[k]
      • 对字符串中从位置 i 开始的剩余部分进行升序排序,得到后继识别码。
    4. 输出结果
      • 输出后继识别码。

    代码实现

    1. 读取输入部分
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cstdio>  
    #include <cstdlib> 
    
    using namespace std;
    
    int cmp(const void *a, const void *b)
    {
        return *(char *)a - *(char *)b;
    }
    
    int main()
    {
        char s[60];
        int i, j, sign, len;
        while (1)
        {
            if (fgets(s, sizeof(s), stdin) == NULL) {  // 将 nullptr 替换为 NULL
                break;
            }
            len = strlen(s);
            if (len > 0 && s[len - 1] == '\n') {
                s[len - 1] = '\0';
            }
            len = strlen(s);  
    
            if (len == 1 && s[0] == '#') {
                break;
            }
    
            sign = 0;
            for (i = len - 1; i >= 1; i--) {
                if (s[i - 1] < s[i]) {
                    sign = 1;
                    break;
                }
            }
    
            if (sign == 0) {
                printf("No Successor\n");
            } else {
                char ma = 120;
                int k;
                for (j = i; j < len; j++) {
                    if (s[j] < ma && s[j] > s[i - 1]) {
                        ma = s[j];
                        k = j;
                    }
                }
                char m = s[i - 1];
                s[i - 1] = s[k];
                s[k] = m;
                qsort(&s[i], len - i, sizeof(char), cmp);
                for (j = 0; j < len; j++) {
                    printf("%c", s[j]);
                }
                printf("\n");
            }
        }
        return 0;
    }
    

    复杂度分析

    1. 时间复杂度
      • 对于每个输入字符串,判断是否存在后继识别码的时间复杂度为(O(n)),其中(n)是字符串的长度。
      • 找到后继识别码的时间复杂度为(O(n))。
      • 对字符串的剩余部分进行排序的时间复杂度为(O(n \log n))。
      • 因此,总的时间复杂度为(O(n \log n))。
    2. 空间复杂度
      • 主要的空间消耗在于存储输入的字符串,空间复杂度为(O(n)),其中(n)是字符串的长度。
    • 1

    信息

    ID
    147
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    4
    已通过
    1
    上传者