C. Phone Numbers - Codeforces Round 466 (Div. 2)
Solutions Codeforces 贪心
Lastmod: 2025-01-03 周五 19:47:17

https://codeforces.com/contest/940/problem/C

题目大意

给出字符串 $S$ 以及长度 $k$, $(|S|,k \le 10^5)$。要求用 $S$ 相同的字符集,构造字典序最小的且字典序大于 $S$ 的,长度为 $k$ 的串 $T$ 。题目保证有解。

简要题解

注意到这里是字符串,和数字的比较大小是不同的。

对于 $k > n$ 的情况,我们只需要在末尾追加最小字符即可。

对于 $k \le n$ 的情况,我们只需生成的串比 $S[0, k -1]$ 严格大。这里我们反着找到,第一个可以增大的位置,将其变大一点,并用最小字符填充后续位置即可。

复杂度

$T$:$O(n + k)$

$S$:$O(n + k)$

代码实现

#include <bits/stdc++.h>
using namespace std;

int io_=[](){ ios::sync_with_stdio(false); cin.tie(nullptr); return 0; }();

using LL = long long;
using ULL = unsigned long long;
using LD = long double;
using PII = pair<int, int>;
using VI = vector<int>;
using MII = map<int, int>;

template<typename T> void cmin(T &x,const T &y) { if(y<x) x=y; }
template<typename T> void cmax(T &x,const T &y) { if(x<y) x=y; }
template<typename T> bool ckmin(T &x,const T &y) { 
    return y<x ? (x=y, true) : false; }
template<typename T> bool ckmax(T &x,const T &y) { 
    return x<y ? (x=y, true) : false; }
template<typename T> void cmin(T &x,T &y,const T &z) {// x<=y<=z 
    if(z<x) { y=x; x=z; } else if(z<y) y=z; }
template<typename T> void cmax(T &x,T &y,const T &z) {// x>=y>=z
    if(x<z) { y=x; x=z; } else if(y<z) y=z; }

// mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
// mt19937_64 rnd_64(chrono::system_clock::now().time_since_epoch().count());

/*
---------1---------2---------3---------4---------5---------6---------7---------
1234567890123456789012345678901234567890123456789012345678901234567890123456789
*/

void solve() {
  int n, k; cin >> n >> k;
  string s; cin >> s;

  set<char> se;
  for (char c : s) se.insert(c);
  
  char smallest = *se.begin();
  
  if (k > n) {
    cout << s;
    k -= n;
    
    for (int i = 0; i < k; i++) {
      cout << smallest;
    }
    cout << '\n';
    return;
  }

  char largest = *--se.end();

  string ans;
  for (int i = k - 1; i >= 0; i--) {
    if (s[i] < largest) {
      auto it = se.find(s[i]);
      it++;
      ans += *it;
      for (int j = i - 1; j >= 0; j--) {
        ans += s[j];
      }

      break;
    }
    ans += smallest;
  }

  reverse(ans.begin(), ans.end());
  cout << ans << '\n';
}

int main() {
  int t = 1; 
  // cin >> t;
  while (t--) {
    solve();
  }
  return 0;
}
Prev: D. Alena And The Heater - Codeforces Round 466 (Div. 2)
Next: B. Our Tanya is Crying Out Loud - Codeforces Round 466 (Div. 2)