D. Dense Subsequence
题目连接:
http://codeforces.com/contest/724/problem/D
Description
You are given a string s, consisting of lowercase English letters, and the integer m.
One should choose some symbols from the given string so that any contiguous subsegment of length m 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 a k 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 string sip1sip2… 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 exceed 100 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.
Sample Input
3
cbabc
Sample Output
a
Hint
题意
给你一个m和一个字符串s
一开始你的now为0,你需要在[now,now+m-1]里面选一个字符,假设选的位置为p,则now=p+1,然后重复
直到now+m-1>=s.size(),并且不能选择使得字典序变得更小的时候,就不选了。
你需要找到字典序最小的答案,答案最后可以排序,选出来的东西。
题解:
暴力枚举最大的字符是什么,然后再贪心的去放,小于这个字符的全选,其他的贪心的去放,使得能够覆盖所有区域。
肯定是放覆盖当前区间最后面的那个。
代码
#include<bits/stdc++.h>
using namespace std;
set<int>S[26];
int m;
string s;
int cnt[26];
int main()
{
cin>>m>>s;
for(int i=0;i<26;i++)
{
int last=-1,lastcur=-1e5,flag=1;
memset(cnt,0,sizeof(cnt));
for(int j=0;j<s.size();j++)
{
if(s[j]==i+'a')
lastcur=j;
else if(s[j]<i+'a'){
last=j;
cnt[s[j]-'a']++;
}
if(j-last>=m){
if(lastcur<=last){
flag=0;
break;
}
last=lastcur;
cnt[i]++;
}
}
if(flag==0)continue;
for(int ii=0;ii<26;ii++)
for(int jj=0;jj<cnt[ii];jj++)
printf("%c",ii+'a');
cout<<endl;
return 0;
}
}