要保证每个长为m的子串有个位置被选掉,切选出的序列排序后字典序最小。
关键是要保证最大的字母字典序最小,所以先遍历,从前往后每m个选一个最小的,在相同字幕里选尽可能靠后的,保证之后字典序最小,然后找到无论如何必须要选的最大字母后,再从前忘后遍历,找出比最大字母小的字母全部选掉。
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#define maxl 100010
#define inf 2000000001
using namespace std;
int m,anslen,len;
char ch[maxl],ans[maxl];
bool in[maxl];
void prework()
{
scanf("%d",&m);
scanf("%s",ch);
}
void mainwork()
{
int now=0,pos,mi,ma=0;
len=strlen(ch);
while(now+m-1<=len-1)
{
mi=inf;
for(int i=now;i<=now+m-1;i++)
if(ch[i]<=mi)
{
mi=ch[i];
pos=i;
}
in[pos]=true;
if(mi>ma) ma=mi;
now=pos+1;
}
for(int i=0;i<len;i++)
if(ch[i]<ma && !in[i])
in[i]=true;
for(int i=0;i<len;i++)
if(in[i])
ans[++anslen]=ch[i];
sort(ans+1,ans+1+anslen);
}
void print()
{
for(int i=1;i<=anslen;i++)
printf("%c",ans[i]);
}
int main()
{
prework();
mainwork();
print();
return 0;
}