水题啊,好不容易遇到会写的1900分
明 显 如 果 在 答 案 中 出 现 了 字 母 x 明显如果在答案中出现了字母x 明显如果在答案中出现了字母x
那 么 小 于 x 的 字 母 一 定 全 选 , 因 为 这 样 使 得 x 最 靠 后 那么小于x的字母一定全选,因为这样使得x最靠后 那么小于x的字母一定全选,因为这样使得x最靠后
所 以 我 们 枚 举 这 个 x 字 母 所以我们枚举这个x字母 所以我们枚举这个x字母
贪 心 的 , 小 于 x 的 全 选 , 等 于 x 的 暂 时 不 选 , 记 录 下 来 贪心的,小于x的全选,等于x的暂时不选,记录下来 贪心的,小于x的全选,等于x的暂时不选,记录下来
后 续 如 果 不 满 足 m 个 的 话 , 就 贪 心 的 去 前 面 拿 一 个 最 近 的 x 后续如果不满足m个的话,就贪心的去前面拿一个最近的x 后续如果不满足m个的话,就贪心的去前面拿一个最近的x
代码也非常的短
46ms也蛮快的
#include <bits/stdc++.h>
using namespace std;
int n,m,vis[30],flag;
char a[1000009];
void isok(char w)
{
//表示本次小于等于w的都去选
int last=0,nxt=-1;
for(int i=0;i<=25;i++) vis[i]=0;
for(int i=1;i<=n;i++)
{
if( a[i]<w )
vis[ a[i]-'a' ]++,last=i;
else if( a[i]==w ) nxt=i;//这是w,暂时不选
if( i-last>=m )
{
if( nxt!=-1&&i-nxt<m )
{
vis[w-'a']++,last=nxt;
continue;
}
return;
}
}
flag=1;
}
int main()
{
cin >> m >> (a+1);
n=strlen(a+1);
for(char i='a';i<='z';i++)
{
isok(i);
if( !flag ) continue;
for(int i=0;i<=25;i++)
while( vis[i]-- ) cout << char(i+'a');
return 0;
}
}