题目
思路
本题用贪心的思路AC。
考虑从后往前找,那么对于一个字符
我们知道只有当它后面包含了未被加入答案的所有字符时它才可选
而第一个可选字符到第一个字符就组成了可行区间
在这个可行区间里找到字典序最小的字符加入答案,然后删除当前字符就好了。
代码
#include<iostream>
#include<cstdio>
using namespace std;
int c[27],wz,cnt,a[27],flag;
char jl;
string s;
int main()
{
freopen("aorder.in","r",stdin);
freopen("aorder.out","w",stdout);
cin>>s;
int len=s.size();
for(int i=0; i<len; i++)
if(!c[s[i]-96])
c[s[i]-96]=1,cnt++;
int last=-1;
while(cnt--)
{
flag=0;
jl=char(127);
for(int i=len-1; i>last; i--)
{
a[s[i]-96]=1;
if(!flag)
{
int w=0;
for(int j=1; j<=26; j++)
{
if(a[j]!=c[j]&&c[j]==1)
{
w=1;
break;
}
}
if(w==0)
flag=1;
}
if(flag==1&&c[s[i]-96]==1)
{
if(s[i]<jl)
jl=s[i],wz=i;
else if(s[i]==jl&&i<wz)
jl=s[i],wz=i;
}
}
printf("%c",jl);
c[jl-96]=0,last=wz;
for(int i=1; i<=26; i++)
a[i]=0;
}
return 0;
}