Codeforce940C (Phone Numbers)
And where the are the phone numbers?
You are given a string s consisting of lowercase English letters and an integer k. Find the lexicographically smallest string t of length k, such that its set of letters is a subset of the set of letters of s and s is lexicographically smaller than t.
It's guaranteed that the answer exists.
Note that the set of letters is a set, not a multiset. For example, the set of letters of abadaba is {a, b, d}.
String p is lexicographically smaller than string q, if p is a prefix of q, is not equal to q or there exists i, such that pi < qi and for all j < i it is satisfied that pj = qj. For example, abc is lexicographically smaller than abcd , abd is lexicographically smaller than abec, afa is not lexicographically smaller than ab and a is not lexicographically smaller than a.
The first line of input contains two space separated integers n and k (1 ≤ n, k ≤ 100 000) — the length of s and the required length of t.
The second line of input contains the string s consisting of n lowercase English letters.
Output the string t conforming to the requirements above.
It's guaranteed that the answer exists.
3 3
abc
aca
3 2
abc
ac
3 3
ayy
yaa
2 3
ba
baa
In the first example the list of strings t of length 3, such that the set of letters of t is a subset of letters of s is as follows: aaa, aab, aac,
aba, abb, abc, aca, acb, .... Among them, those are lexicographically greater than abc: aca, acb, .... Out of those the lexicographically smallest is aca.
分析:题意是找出按字典序的下一个长度为k的字符串。
当n<k时,在原字符串加上字典序最小的字符即可;
当n>=k时,贪心,从k-1到0找到不是最大字符的一位j,然后s[j]赋值为按字典序的下一个字符,
j以后的全部为赋值为字典序最小的字符。
#include<cstdio> #include<cstring> using namespace std; char s[200000]; int b[30]; char a[30]; int main() { int N,k; scanf("%d%d",&N,&k); scanf("%s",s); for(int i=0;i<N;i++) b[s[i]-'a']++; int cnt=0; for(int i=0;i<26;i++) if(b[i]) a[cnt++]='a'+i; cnt--; if(k>N) { s[k]='\0'; for(int i=N;i<k;i++) s[i]=a[0]; printf("%s\n",s); } else//找出那个位置 { s[k]='\0'; for(int i=k-1;i>=0;i--) { if(s[i]==a[cnt]) {s[i]=a[0];continue;} else { int j=0; for(;j<=cnt;j++) { if(s[i]<a[j]) break; } s[i]=a[j]; break; } } printf("%s\n",s); } return 0; }
作者:ACRykl —— O ever youthful,O ever weeping!
出处:http://www.cnblogs.com/ACRykl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。