【codeforces 724D】【贪心】 Dense Subsequence 【一个字符串,按照一定的区间要求从中选出一些字符,使得这串字符的sort后字典序最小】
2016-10-09 20:29
621 查看
传送门:D. Dense Subsequence
描述:
D. Dense Subsequence
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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.
Examples
input
output
input
output
input
output
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".
题意:
给你一个字符串,让你从中选出一串字符,使得这串字符的sort后字典序最小,选字符的要求是如果上一个选的是i 那么[i+1,i+m]中至少选一个,[1,m]中必须选一个
思路:
贪心,先考虑只由'a'-c的字符组成该字符串,首先有‘a’的话肯定是拿'a'越多越好,拿'b'也是越多越好(aaabbXX肯定比aaabXXX字典序小),也就c字符需要特判一下,因为c字符不是越多越好,而是越少越好,只有在满足前面的越多越好的前提下,不得不拿c才拿。
有了上面的策略我们具体做的时候就先满足区间长度不超过m的条件扫一遍字符串,再按字典序小的加入生成的字符串中策略扫一遍字符串,然后就好了。
比赛的时候贪心策略少考虑了点_(:зゝ∠)_ ,贪心没想象中这么简单!!!
代码:
#include <bits/stdc++.h>
#define pr(x) cout << #x << "= " << x << " " ;
#define pl(x) cout << #x << "= " << x << endl;
#define ll __int64
#define mod 1000000007
using namespace std;
#define mst(ss,b) memset(ss,b,sizeof(ss));
#define rep(i,k,n) for(int i=k;i<=n;i++)
const int N=1e5+10;
char s
,a,mx='a';
int vis
,top=0,m;
int main(){
scanf("%d",&m);
scanf("%s",s+1);
int n=strlen(s+1);
int now=1;
while(now+m-1<=n){
int res=now;
rep(i, now+1, now+m-1){
if(s[i]<=s[res])res=i;
}a[++top]=s[res];
vis[res]=1;
mx=max(mx, a[top]);
now=res+1;
}
rep(i, 1, n)if(!vis[i] && s[i]<mx)a[++top]=s[i];//贪心把字典序小的加入生成的字符串中
sort(a+1, a+top+1);
printf("%s\n", a+1);
return 0;
}
描述:
D. Dense Subsequence
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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.
Examples
input
3 cbabc
output
a
input
2 abcab
output
aab
input
3
bcabcbaccba
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".
题意:
给你一个字符串,让你从中选出一串字符,使得这串字符的sort后字典序最小,选字符的要求是如果上一个选的是i 那么[i+1,i+m]中至少选一个,[1,m]中必须选一个
思路:
贪心,先考虑只由'a'-c的字符组成该字符串,首先有‘a’的话肯定是拿'a'越多越好,拿'b'也是越多越好(aaabbXX肯定比aaabXXX字典序小),也就c字符需要特判一下,因为c字符不是越多越好,而是越少越好,只有在满足前面的越多越好的前提下,不得不拿c才拿。
有了上面的策略我们具体做的时候就先满足区间长度不超过m的条件扫一遍字符串,再按字典序小的加入生成的字符串中策略扫一遍字符串,然后就好了。
比赛的时候贪心策略少考虑了点_(:зゝ∠)_ ,贪心没想象中这么简单!!!
代码:
#include <bits/stdc++.h>
#define pr(x) cout << #x << "= " << x << " " ;
#define pl(x) cout << #x << "= " << x << endl;
#define ll __int64
#define mod 1000000007
using namespace std;
#define mst(ss,b) memset(ss,b,sizeof(ss));
#define rep(i,k,n) for(int i=k;i<=n;i++)
const int N=1e5+10;
char s
,a,mx='a';
int vis
,top=0,m;
int main(){
scanf("%d",&m);
scanf("%s",s+1);
int n=strlen(s+1);
int now=1;
while(now+m-1<=n){
int res=now;
rep(i, now+1, now+m-1){
if(s[i]<=s[res])res=i;
}a[++top]=s[res];
vis[res]=1;
mx=max(mx, a[top]);
now=res+1;
}
rep(i, 1, n)if(!vis[i] && s[i]<mx)a[++top]=s[i];//贪心把字典序小的加入生成的字符串中
sort(a+1, a+top+1);
printf("%s\n", a+1);
return 0;
}
相关文章推荐
- 给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢? 输出需要删除的字符个数。
- poj 1328 Radar Installation 已知一定数量的区间,求最小数量的点,使得每个区间内斗至少存在一个点 贪心
- 给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
- 腾讯 2017 暑假实习生编程题(一):给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢? 输出需要删除的字符个数。
- 给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢? 输出需要删除的字符个数。
- 给定一个字符串a,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长? 输出需要删除的字符个数。
- 从命令行中输入一个字符串,要求从中随机选择6个字符
- 将一个字符串数组中的字符串拼接出来,使得字典序最小
- 从键盘输入一个字符串,按照字符顺序从小到大进行排序,并要求删除重复的的字符。
- 给出一个字符串,要求插入最少的字符,使得原字符串为一个回文串
- RGB排序,一个字符串,里面只有三种字符R G B,所有的R都在G的前面,所有的G都在B的前面。将给定字符串按照此规律排序。要求不允许用辅助空间,复杂度控制在O(N)。
- )RGB排序,一个字符串,里面只有三种字符R G B,所有的R都在G的前面,所有的G都在B的前面。将给定字符串按照此规律排序。要求不允许用辅助空间,复杂度控制在O(N)。遍历一遍就排好序。
- 转:从键盘输入一个字符串,按照字符顺序从小到大进行排序,并要求删除重复的的字符。
- 【codeforces 721D】【贪心 堆】D. Maxim and Array 【给出n个数,k次机会,每次使得任意一个数字减少或者加上x,使得最后的乘积最小,最后的n个数大小】
- leetcode 316. Remove Duplicate Letters 去除重复字符字典序最小字符串+贪心+递归
- C++输入一个字符串,把其中的字符按照逆序输出的两种方法
- C++输入一个字符串,把其中的字符按照逆序输出的两种方法解析
- 有一个字符串,内有若干字符,输入一个字符,要求程序将字符串中该字符删去。
- pojg2744找一个最长的字符串x,使得对于已经给出的字符串中的任意一个y,x或者是y的子串,或者x中的字符反序之后得到的新字符串是y的子串。
- 给定一个字符串里面只有"R" "G" "B" 三个字符,请排序,最终结果的顺序是R在前 G中 B在后。 要求:空间复杂度是O(1),且只能遍历一次字符串。