CSU-ACM2017暑假集训比赛2 CodeForces

来源:互联网 发布:哪里有im域名 编辑:程序博客网 时间:2024/06/06 01:05

题目:

You are given a string s, consisting of lowercase English letters, and the integerm.

One should choose some symbols from the given string so that any contiguous subsegment of lengthm has at least one selected symbol. Note that here we choose positions of symbols, not the symbols themselves.

Then one uses the chosen symbols to form a new string. All symbols from the chosen position should be used, but we are allowed to rearrange them in any order.

Formally, we choose a subsequence of indices 1 ≤ i1 < i2 < ... < it ≤ |s|. The selected sequence must meet the following condition: for every j such that 1 ≤ j ≤ |s| - m + 1, there must be at least one selected index that belongs to the segment[j,  j + m - 1], i.e. there should exist ak from 1 to t, such that j ≤ ik ≤ j + m - 1.

Then we take any permutation p of the selected indices and form a new stringsip1sip2...sipt.

Find the lexicographically smallest string, that can be obtained using this procedure.

Input

The first line of the input contains a single integer m (1 ≤ m ≤ 100 000).

The second line contains the string s consisting of lowercase English letters. It is guaranteed that this string is non-empty and its length doesn't exceed100 000. It is also guaranteed that the number m doesn't exceed the length of the string s.

Output

Print the single line containing the lexicographically smallest string, that can be obtained using the procedure described above.

Example
Input
3cbabc
Output
a
Input
2abcab
Output
aab
Input
3bcabcbaccba
Output
aaabb
Note

In the first sample, one can choose the subsequence {3} and form a string "a".

In the second sample, one can choose the subsequence {1, 2, 4} (symbols on this positions are 'a', 'b' and 'a') and rearrange the chosen symbols to form a string "aab".


题意:给你一个字符串和一个数m,要你从中选出一些字符来,使得在原串中每一个长度为m的连续子串中至少有一个字符在是在你选出来的那些字符中的,并且还要求你选出来的字符形成的字符串排序后字典序最小。

思路:首先明确 aab的字典序比aaab的要大,但是aa的字典序比aaa的要小,于是可以明确一个贪心策略,如果你要从字符串中选出来的最大字母是b,那么你可以把所有的a都拿出来以获得最小的字典序。所以只用线性扫描一遍数组,每次看m个字符,选取m个字符中最小的一个字符,当然要尽可能选靠后的,比如m=3时 ababca这个串第一次扫aba这三个时要选第三个a,然后继续往你选的那个后面扫,同时记录一下你取到的字符的最大的那个,方便最后构造最小字典序的结果。

代码:

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<string>#include<vector>#include<stack>#include<bitset>#include<cstdlib>#include<cmath>#include<set>#include<list>#include<deque>#include<map>#include<queue>using namespace std;typedef long long ll;const double PI = acos(-1.0);const double eps = 1e-6;const int INF = 1000000000;const int maxn = 111111;int T,n,m;char s[maxn],a[maxn],mx='a';int vis[maxn];int main(){    scanf("%d%s",&m,s);    int len=strlen(s);    int pos=0,cnt=0;    while(pos+m-1<len)    {        int res=pos;//pos记录前一次扫描选到的字符的位置        for(int i=pos+1;i<=pos+m-1;i++)        {            if(s[i]<=s[res])                res=i;//res记录本次扫描取的字符的位置        }        a[cnt++]=s[res];        vis[res]=1;        mx=max(mx,s[res]);//mx记录最大字符        pos=res+1;    }    for(int i=0;i<len;i++)//构造最小字典序答案    {        if(vis[i]==0&&s[i]<mx)            a[cnt++]=s[i];    }    a[cnt]='\0';    sort(a,a+cnt);    printf("%s\n",a);}

原创粉丝点击