zoukankan      html  css  js  c++  java
  • 正睿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;
    }
    
  • 相关阅读:
    实验五 shell脚本编程
    实验四 Linux系统C语言开发环境学习
    实验三 Linux系统用户管理及VIM配置
    实验二 Linux系统简单文件操作命令
    实验一 Linux系统与应用准备
    实验八 进程间通信
    实验七 信号
    实验六 进程基础
    实验五 shell脚本编程
    实验四 Linux系统搭建C语言编程环境
  • 原文地址:https://www.cnblogs.com/yywxdgy/p/13062425.html
Copyright © 2011-2022 走看看