Don't Be a Subsequence

6597: Don't Be a Subsequence

时间限制: 1 Sec  内存限制: 128 MB
提交: 270  解决: 59
[提交] [状态] [讨论版] [命题人:admin]

题目描述

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子串的字符串中,先满足长度最短、然后满足字典序最小的字符串!

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

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+50;
int Next[maxn][29],now[29],now_tot[maxn];
char s[maxn];
set<int>S;
vector<char>ans;
int cnt=26,len,tot,tmp;
int main()
{
    scanf("%s",s+1);
    len=strlen(s+1);
    tot=0;
    memset(now,0,sizeof(now));
    memset(now_tot,0,sizeof(now_tot));
    memset(Next,0,sizeof(Next));
    for(int i=len; i>=1; i--)
    {
        now_tot[i]=tot;
        S.insert(s[i]-'a');
        if(S.size()==cnt)
        {
            tot++;
            S.clear();
        }
    }
    if(tot==0)
    {
        for(int i=0; i<cnt; 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<cnt;j++)
            {
                Next[i][j]=now[j];
            }
            now[s[i]-'a']=i;
        }
        tmp=0;
        for(int i=0;i<cnt;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<cnt;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<cnt;i++)
        {
            if(Next[tmp][i]==0)
            {
                ans.push_back(i+'a');
                break;
            }
        }
    }
    for(int i=0;i<ans.size();i++)
    {
        printf("%c",ans[i]);
    }
    printf("
");
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/lglh/p/9400588.html