• 【每日一题】补档 CF1799C. Double Lexicographically Minimum | 构造 | 简单


    题目内容

    原题链接

    给定一个长度为 n n n 的只有小写字母的字符串 s s s ,随意排列这个字符串,使得字符串正着和反着的最大字典序最小。

    数据范围

    • 1 ≤ n ≤ 1 0 5 1\leq n\leq 10^5 1n105
    • s s s 中都是小写字母

    题解

    我们保证首尾字符尽可能相等,且字符尽可能小。

    统计每个字符的出现次数。

    记录最小字符 a a a 出现了 c a ca ca 次,大于最小字符 a a a 的字符 b b b 出现了 c b cb cb 次,大于 b b b 的字符 c c c 出现了 c c cc cc 次。

    • c a = 1 , c b = 0 ca=1,cb=0 ca=1,cb=0 ,那么直接放
    • c a ≥ 2 ca\geq 2 ca2 ,那么首尾放 a a a 即可
    • c a = 1 , c b = 1 ca=1,cb=1 ca=1,cb=1 ,那么一边放 a a a 一边放 c c c 即可,剩余部分从 c c c 一边开始从小到大放
    • c a = 1 , c b > 1 ca=1,cb>1 ca=1,cb>1
      • c c = 0 cc=0 cc=0 ,那么两边放 b b b,把 a a a 留在最中间
      • c c > 0 cc>0 cc>0 ,那么一边放 a a a 一边放 b b b,剩余部分从 b b b 一边开始从小到大放。
        c c > 0 cc>0 cc>0 如果不放 a a a ,那就是放两个 b b b
        考虑放 a a a 与不放 a a a ,对于 a a a 这边来说不是决定最大字典序的模块,放了 a a a ,我就可以将剩余字符都按从小到大的顺序给 b b b 一边。但是如果不放 a a a ,我就要拿两个 b b b 放到两边,本来我的最小的是 b b . . . c c . . . d d . . . bb...cc...dd... bb...cc...dd... 这种形式,现在少了一个就成了 b c c . . . d d . . . bcc...dd... bcc...dd... 。那么这个 a a a 放到哪,后面一定是接一个从最大字符到最小字符的。但是我本来是 b b c c . . . d d . . . bbcc...dd... bbcc...dd... 的形式,变成了 b c c . . . d d . . . bcc...dd... bcc...dd... 形式,字典序就变大了,所以此时是一边放 a a a 一边放 b b b 最优解。

    代码,

    #include 
    using namespace std;
    
    const int N = 100010;
    char s[N];
    char ans[N];
    int cnt[26];
    int n;
    
    void op(int& x, int& y, int i, int j) {
        ans[x] = i + 'a';
        ans[y] = j + 'a';
        cnt[i] -= 1;
        cnt[j] -= 1;
        x += 1;
        y -= 1;
    }
    
    void solve() {
        memset(cnt, 0, sizeof cnt);
        scanf("%s", s + 1);
        n = strlen(s + 1);
    
        if (n == 1) {
            puts(s + 1);
            return ;
        }
    
        for (int i = 1; i <= n; ++i) {
            cnt[s[i] - 'a'] += 1;
        }
    
        ans[n + 1] = 0;
        int i = 1, j = n;
        while (i < j) {
            int id[3] = {-1, -1, -1};
            for (int c = 0; c < 26; ++c) {
                if (cnt[c] > 0) {
                    if (id[0] == -1) id[0] = c;
                    else if (id[1] == -1) id[1] = c;
                    else if (id[2] == -1) id[2] = c;
                    else break;
                }
            }
    
            if (id[0] != -1 && cnt[id[0]] >= 2) {
                op(i, j, id[0], id[0]);
                continue ;
            }
    
            if (id[0] != -1 && id[1] != -1 && cnt[id[0]] == 1 && cnt[id[1]] == 1) {
                op(i, j, id[0], id[1]);
                break;
            }
    
            if (id[2] == -1 && cnt[id[1]] >= 2) {
                op(i, j, id[1], id[1]);
                continue ;
            } else {
                op(i, j, id[0], id[1]);
                break;
            }
        }
    
        for (int k = i, c = 25; k <= j; ++k) {
            while (c > 0 && cnt[c] == 0) c -= 1;
            ans[k] = c + 'a';
            cnt[c] -= 1;
        }
    
        reverse(ans + 1, ans + n + 1);
    
        printf("%s\n", ans + 1);
    }
    
    int main()
    {
        int T = 1;
        scanf("%d", &T);
        while (T--) {
            solve();
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
  • 相关阅读:
    luckysheet的一点使用心得
    什么是大语言模型以及如何构建自己的大型语言模型?
    Kafka之Controller(Broker的领导者)
    蒙码像专属ob
    阿里云的ACP认证与ACE认证含金量高吗?
    基于JAVA汽车站车辆运管系统计算机毕业设计源码+数据库+lw文档+系统+部署
    vivo 万台规模 HDFS 集群升级 HDFS 3.x 实践
    Java面试常见题:手写单向链表的实现思路
    每个人都应该去学写作
    【无标题(PC+WAP)花卉租赁盆栽绿植类pbootcms站模板
  • 原文地址:https://blog.csdn.net/weixin_43900869/article/details/134078985