• XEN 3166


    XEN 3166

    这题原题是spj,校oj上只用判断yes no,不过也差不多

    题意分析之后就是求两个东西:

    • 字典序最小的长度为m的子序列
    • 同时这个字典序严格大于某个字符串

    用序列自动机 先尽量相同,然后再考虑严格大于

    #include <bits/stdc++.h>
     
    using namespace std;
    const int maxn = 200010;
    int last[27], nxt[maxn][27], len;
     
    void init(const char s[]) {
        len = (int) strlen(s);
        for (int i = 0; i < 26; ++i) last[i] = len + 1;
        for (int i = len; i >= 1; i--) {
            for (int j = 0; j < 26; ++j) {
                nxt[i][j] = last[j];
            }
            last[s[i - 1] - 'A'] = i;
        }
        for (int j = 0; j < 26; ++j) {
            nxt[0][j] = last[j];
        }
    }
     
    char s[2][maxn];
    int n, m;
     
    int solve(char pre[], char ans[], const char name[]) {
        if (len < m) return false;
        if (pre[1] == name[0]) {
            if (m <= 1) return 0;
            int a = 0, b = 0, c = 0;
            for (int i = 1, j = 1; i < m && j <= len; ++i) {
                ans[i] = pre[i];
                for (int k = pre[i + 1] - 'A' + 1; k < 26; ++k) {
                    if (i + len - nxt[j][k] + 1 >= m) {
                        a = i;
                        b = j;
                        c = k;
                        break;
                    }
                }
                j = nxt[j][pre[i + 1] - 'A'];
            }
            if (!a) return 0;
            ans[a + 1] = char(c + 'A');
            //
            for (int i = a + 1, j = nxt[b][c]; i < m; ++i) {
                for (int k = 0; k < 26; ++k) {
                    if (i + len - nxt[j][k] + 1 >= m) {
                        ans[i + 1] = char(k + 'A');
                        j = nxt[j][k];
                        break;
                    }
                }
            }
        } else {
            ans[1] = name[0];
            for (int i = 1, j = nxt[0][name[0] - 'A']; i < m; ++i) {
                for (int k = 0; k < 26; ++k) {
                    if (i + len - nxt[j][k] + 1 >= m) {
                        ans[i + 1] = char(k + 'A');
                        j = nxt[j][k];
                        break;
                    }
                }
            }
        }
        return 1;
    }
     
    string p[1010];
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        cin >> n >> m;
        for (int i = 1; i <= n; ++i) {
            cin >> p[i];
        }
        sort(p + 1, p + 1 + n);
        bool flag = 1;
        for (int i = 1; i <= n; ++i) {
            init(p[i].c_str());
            if (!solve(s[i % 2], s[1 - i % 2], p[i].c_str())) {
                flag = 0;
                break;
            }
        }
        if (flag) cout << "YES" << '
    ';
        else cout << "NO" << '
    ';
     
        return 0;
    }
    
    不要忘记努力,不要辜负自己 欢迎指正 QQ:1468580561
  • 相关阅读:
    标签平滑Label Smoothing
    py 中传参时**符号学习
    RoBERTa模型学习
    获取bert所有隐层的输出
    json.dumps||ensure_ascii
    nn.LSTM输入、输出、参数及pad
    py中的heapq操作
    fastnlp中的CRF补齐的padding?
    P3393 逃离僵尸岛 最短路dijkstra
    P2057 [SHOI2007]善意的投票 最小割
  • 原文地址:https://www.cnblogs.com/smallocean/p/11516359.html
Copyright © 2020-2023  润新知