けんちょんの競プロ精進記録

競プロの精進記録や小ネタを書いていきます

Codeforces Round #609 (Div. 1) A. Long Beautiful Integer (R1700)

こういうのは、いかにシンプルにできるか...

問題へのリンク

問題概要

 N 桁の整数  a が与えられる (文字列として)。leading zero はない。整数  K (\lt N) が与えられる。 a 以上の整数  b であって

  •  b i 桁目と  i+K 桁目の値は等しい

という条件を満たす最小値を求めよ。

制約

  •  2 \le N \le 10^{5}

考えたこと

落ち着くんだ...ひとまず、最悪でも 999...9 (N 桁) が条件を満たすので、桁数を増やす必要はない。あと、上から  K 桁分を決めれば全部決まるので、上から  K 桁を決める問題ということになる。

  • もし、上から  K 桁のところが元のままでも、それを繰り返したときに  a 以上になるなら、それが答え
  • それが  a 未満であるならば、上から  K 桁の部分を 1 増やしたものが答え

ということになる。

#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
#include <unordered_map>
using namespace std;
 
int N, K;
string a;
 
string plusone(string s) {
    int id = (int)s.size() - 1;
    while (s[id] == '9') {
        s[id] = '0';
        --id;
    }
    ++s[id];
    return s;
}
 
string solve() {
    string b = a;
    for (int i = K; i < N; ++i) b[i] = a[i%K];
    if (b >= a) return b;
    string res = "";
    string prefix = plusone(a.substr(0, K));
    for (int i = 0; i < N; ++i) res += prefix[i%K];
    return res;
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    while (cin >> N >> K >> a) {
        string res = solve();
        cout << res.size() << endl;
        cout << res << endl;
    }
}