• 正睿2020普转提【第六套】串


    T2

    题目

    睿爸喜欢玩串串。

    睿爸手里有一个只有小写字母组成的串(S) , 他希望你在里面找出一个字典序最小的子序列(T) , 使得去掉子序列(T)的部分剩下的串是(T)的一个排列。

    如果无法找到,请输出("mathrm{Clbtxdy!}")

    Solution

    贪心。

    对于每一位我们贪心选取合法、字典序最小的(同时尽可能取位置靠前的)字母。

    一个方案合法:当且仅当取掉这个字母之后依旧至少有解。

    判断某一字母是否合法,只需统计这个字母用的次数是否超过总数的一半、之后每种字母还有多少个。

    (mathrm{Code:})

    #include <cstring>
    #include <iostream>
    const int N = 210;
    int n;
    char a[N];
    int t[27], c[N][27], b[N];
    
    main() {
        freopen("string.in", "r", stdin);
        freopen("string.out", "w", stdout);
        scanf("%s", a + 1);
        n = strlen(a + 1);
        for (int i = 1; i <= n; ++i) {
            int x = a[i] - 'a';
            for (int j = 0; j <= 26; ++j) c[i][j] = c[i - 1][j];
            ++t[x];
            ++c[i][x];
        }
        for (int i = 0; i <= 26; ++i) {
            if (t[i] & 1) {
                puts("Clbtxdy!");
                return 0;
            }
        }
        int now = 0;
        for (int i = 1; i <= n; ++i) {
            int x = a[i] - 'a';
            while (c[i][x] * 2 > t[x] + 2 * b[x]) {
                for (int j = 0; j <= 26; ++j) {
                    if (c[i][j] - c[now][j] && b[j] * 2 < t[j]) {
                        ++b[j];
                        putchar(j + 'a');
                        for (int k = now + 1; k <= i; ++k)
                            if (a[k] == j + 'a') {
                                now = k;
                                break;
                            }
                        break;
                    }
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    “automation服务器不能创建对象”的问题的解决方案大全
    转载区分C#中的Abstract函数和Virtual函数
    DOS批处理
    数据库设计范式
    java 内存查看工具
    Java内存溢出详解
    Struts2 循环编辑指定次数
    Selenium 使用
    spring security 获取当前用户信息
    由MyEclipse内存不足谈谈JVM内存
  • 原文地址:https://www.cnblogs.com/yywxdgy/p/13062425.html
Copyright © 2020-2023  润新知