cf886 D. Restoration of string

题意:

如果一个字符串的子串出现的次数大于任何子串出现的次数,那么这个子串就是 \(\text{most frequent}\)

给 n 个 \(\text{most frequent}\) 子串,问最短的原串。

如果有多个最短原串,取字典序最小的那个。没有就输出 NO

思路:

https://www.cnblogs.com/CQzhangyu/p/8052899.html

const signed N = 1e5 + 3;
int n, m, pre[26], nxt[26];
char s[N]; bool vis[26];

signed main() {
    iofast;
    memset(pre, -1, sizeof pre), memset(nxt, -1, sizeof nxt);
    cin >> n;
    while(n--) {
        cin >> s; m = strlen(s);
        vis[s[0]-'a'] = 1;
        for(int i = 1; s[i]; i++) { //找出不相交链
            int u = s[i-1]-'a', v = s[i]-'a';
            if(~nxt[u] && nxt[u] != v || ~pre[v] && pre[v] != u)
                return cout << "NO", 0;
            nxt[u] = v, pre[v] = u, vis[v] = 1;
        }
    }

    string ans = ""; //用所有链构造答案
    for(int i = 0; i < 26; i++)
        if(vis[i] && pre[i] == -1)
            for(int j = i; ~j; j = nxt[j])
                vis[j] = 0, ans.pb(j+'a');

    for(int i = 0; i < 26; i++) //环
        if(vis[i]) return cout << "NO", 0;

    cout << ans;
}

posted @ 2022-03-27 11:47  Bellala  阅读(74)  评论(0)    收藏  举报