940C Phone Numbers

传送门

题目大意

给你两个数字n和k,给你一个字符串s,n是s的长度,求字母集合是s的字母集合子集的字典序大于s的长度为k的字典序最小的字符串t

分析

将字符转化为数字,然后分两种情况处理:

   1.n<k:t的前n为是s,后面几位是s中字典序最小的字母

   2.n>=k:将t赋为s的前k位,从t的最后一位开始,如果字符子集中有字典序比它大的则将其替换为比其大的中字典序最小的字符,否则将其替换为整个字符子集中字典序最小的字符,在此位的前一位重复此步骤

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
char s[110000],t[110000];
bool is[50];
int a[110000],b[110000],c[50];
int n,m,j,k,cnt=0;
inline void gob(int pl){
      if(b[pl-1]<c[cnt]){
          for(int i=1;i<=cnt;i++)
                if(c[i]>b[pl-1]){
                  b[pl-1]=c[i];
                  return;
               }
          }
      else {
      b[pl-1]=c[1];
      gob(pl-1);
      }
}
int main()
{     int i;
      cin>>n>>k;
      scanf("%s",s+1);
      for(i=1;i<=n;i++){
         a[i]=s[i]-'a';
         if(!is[a[i]])c[++cnt]=a[i];
         is[a[i]]=1;
      }
      sort(c+1,c+1+cnt);
      for(i=1;i<=min(n,k);i++){
          b[i]=a[i];
      }
      if(k>n){
          for(i=n+1;i<=k;i++)b[i]=c[1];
      }
      else {
          if(is[b[k]+1]){
          b[k]+=1;
        }
            else if(b[k]<c[cnt]){
                for(i=1;i<=cnt;i++)
                   if(c[i]>b[k]){
                     b[k]=c[i];
                     break;
                   }
                 }
            else {
                b[k]=c[1];
                gob(k);
            }
      }
      for(i=1;i<=k;i++)
         t[i]=(b[i]+'a');
      printf("%s",t+1);
      return 0;
}

posted @ 2018-02-25 18:53  水题收割者  阅读(346)  评论(0编辑  收藏  举报