Don't Be a Subsequence(UPC 6597)

题目描述

A subsequence of a string S is a string that can be obtained by deleting zero or more characters from S without changing the order of the remaining characters. For example, arc, artistic and (an empty string) are all subsequences of artistic; abc and ci are not.
You are given a string A consisting of lowercase English letters. Find the shortest string among the strings consisting of lowercase English letters that are not subsequences of A. If there are more than one such string, find the lexicographically smallest one among them.

Constraints
1≤|A|≤2×105
A consists of lowercase English letters.

输入

Input is given from Standard Input in the following format:
A

输出

Print the lexicographically smallest string among the shortest strings consisting of lowercase English letters that are not subsequences of A.

样例输入

atcoderregularcontest

样例输出

b

提示

The string atcoderregularcontest contains a as a subsequence, but not b.

来源/分类

ABC071&ARC081 

题目给出一个序列s,要求一个序列ans,ans满足两个条件,不是s的子序列,且字典序最小。

思路:从后往前预处理一遍字符串,设置一个tot,记录出现了几次a~z,没全部出现一次就加一,一个Next[][]数组,记录i位置j字符的下一个出现位置,now[i]记录i字符第一次出现的位置,这样我们就相当域将整个字符串按tot的值分成了多个区间,我们先找出第一个区间没出现的且最小的字符,然后依次枚举下一个字符,枚举方法为,当前位置为pos, 枚举Next[pos][i],只要now[next[i][j]] 与now[pos]相差为一就行,因为这样是相当于了两个字符不在一个区间,所以是可以的。

AC代码:

#include<bits/stdc++.h>
#define mem(a, b) memset(a, b, sizeof(b))
using namespace std;
const int maxn = 2e5 + 10;
int Next[maxn][30], now[30], now_tot[maxn];
char s[maxn];
set<int>S;
vector<int>ans;
int main()
{
    ios::sync_with_stdio(false);
    while(cin >> s+1)
    {
        ans.clear();
        int len = strlen(s+1);
        int tot = 0;
        mem(now, 0);
        mem(now_tot, 0);
        mem(Next, 0);
        S.clear();
        for(int i = len; i >= 1; i--)
        {
            now_tot[i] = tot;
            S.insert(s[i]-'a');
            if(S.size() == 26)
            {
                tot++;
                S.clear();
            }
        }
        if(tot == 0)
        {
            for(int i = 0; i < 26; i++)
            {
                if(S.count(i) == 0)
                {
                    ans.push_back(i+'a');
                    break;
                }
            }
        }
        else
        {
            for(int i = len; i>= 1; i--)
            {
                for(int  j = 0; j < 26; j++)
                {
                    Next[i][j] = now[j];
                }
                now[s[i]-'a'] = i;
            }
            int tmp = 0;
            for(int i = 0; i < 26; i++)
            {
                if(S.count(i) == 0)
                {
                    tmp = now[i];
                    ans.push_back(s[tmp]);
                    break;
                }
            }
            for(int i = 1; i < tot; i++)
            {
                for(int j = 0; j < 26; j++)
                {
                    if(now_tot[Next[tmp][j]] == now_tot[tmp]-1)
                    {
                        tmp = Next[tmp][j];
                        ans.push_back(s[tmp]);
                        break;
                    }
                }
            }
            for(int i = 0; i < 26; i++)
            {
                if(Next[tmp][i] == 0)
                {
                    ans.push_back(i+'a');
                    break;
                }
            }
        }
        for(int i = 0; i < ans.size(); i++)
        {
            cout << char(ans[i]);
        }
        cout << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/MALONG11124/article/details/81268206