And where the are the phone numbers?
You are given a string s consisting of lowercase English letters and an integerk. Find the lexicographically smallest stringt of length k, such that its set of letters is a subset of the set of letters ofs and s is lexicographically smaller thant.
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 ofabadaba is {a, b, d}.
String p is lexicographically smaller than stringq, if p is a prefix ofq, is not equal to q or there exists i, such thatpi < qi and for allj < i it is satisfied that pj = qj. For example,abc is lexicographically smaller than abcd , abd is lexicographically smaller thanabec, afais 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 ofs and the required length of t.
The second line of input contains the string s consisting ofn 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 oft is a subset of letters of s is as follows: aaa, aab, aac, aba, abb, abc, aca, acb, .... Among them, those are lexicographically greater thanabc: aca,acb, .... Out of those the lexicographically smallest isaca.
只需将原字符串的前k个字符串进行操作,取出前k个字符串,并询问第k个字母是否为出现过的字母中最大的,如果是向前询问直到那个字母不是最大的,然后将前面的字符串原样输出,将那个不是最大的字母换成出现过的字母的比他大一点的字母,之后的字母全换成最小的就行了。说得有点乱,看代码吧。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<math.h>
#include<iostream>
#include<queue>
#include<map>
#include<vector>
#include<stack>
#define inf 0x3fffffff
using namespace std;
typedef long long LL;
const int N=1e5+1;
char s[N];
bool vis[30];
int main()
{
int n,k,mina,maxa;
while(~scanf("%d%d",&n,&k))
{
mina=30,maxa=0;
memset(vis,false,sizeof(vis));
scanf("%s",s);
for(int i=0;s[i]!='\0';i++)
{
vis[s[i]-'a']=true;
mina=min(mina,s[i]-'a');
maxa=max(maxa,s[i]-'a');
}
if(k>n)
{
printf("%s",s);
for(int i=n;i<k;i++)
printf("%c",mina+'a');
printf("\n");
}
else
{
for(int i=k-1;i>=0;i--)
{
if(s[i]-'a'!=maxa)
{
for(int j=0;j<i;j++)
printf("%c",s[j]);
for(int j=0;j<26;j++)
{
if(vis[j]&&j>s[i]-'a')
{
printf("%c",j+'a');
break;
}
}
for(int j=0;j<k-1-i;j++)
printf("%c",mina+'a');
printf("\n");
break;
}
}
}
}
}

本文介绍了一种算法,用于从给定字符串中构建长度为k的新字符串,该字符串的字母集合是原字符串的子集,同时确保新字符串字典序大于原字符串,并在所有符合条件的字符串中字典序最小。
490

被折叠的 条评论
为什么被折叠?



