Codeforces Round #350 Div2 F: Restore a Number
解法
含むべき部分文字列以外の部分は、残った数字でできるだけ小さい整数を作れば良い。
求めるべき文字列は3つのうちのいずれかである。
含むべき部分文字列をTとすると、
- Tを先頭に含むもの。
- Tの1桁目の数字をqとした時に、...qqqqqT... となっているもの。
- Tの1桁目の数字をqとした時に、...Tqqqqq... となっているもの。
コード
#include <bits/stdc++.h> using namespace std; int main() { cin.tie(0); ios::sync_with_stdio(false); string S, T; cin >> S >> T; vector<int> cnts(10, 0); for (int i = 0; i < S.size(); ++i) { int k = S[i] - '0'; cnts[k]++; } for (int i = 0; i < T.size(); ++i) { int k = T[i] - '0'; cnts[k]--; } for (int i = 1;; ++i) { string k = to_string(S.size() - i); int l = k.size(); if (l == i) { for (int j = 0; j < k.size(); ++j) { cnts[k[j] - '0']--; } break; } } string head = ""; vector<int> head_cnts = cnts; if (T[0] == '0') { for (int i = 1; i < 10; ++i) { if (head_cnts[i] > 0) { head.push_back(i + '0'); head_cnts[i]--; break; } } } head += T; for (int i = 0; i < 10; ++i) { for (int j = 0; j < head_cnts[i]; ++j) { head.push_back(i + '0'); } } vector<int> sub_head_cnts = cnts; string sub_head = ""; for (int i = 1; i < 10; ++i) { if (sub_head_cnts[i] > 0) { sub_head.push_back(i + '0'); sub_head_cnts[i]--; break; } } for (int i = 0; i < 10; ++i) { if (i == T[0] - '0') sub_head += T; for (int j = 0; j < sub_head_cnts[i]; ++j) { sub_head.push_back(i + '0'); } } vector<int> sub_tail_cnts = cnts; string sub_tail = ""; for (int i = 1; i < 10; ++i) { if (sub_tail_cnts[i] > 0) { sub_tail.push_back(i + '0'); sub_tail_cnts[i]--; break; } } for (int i = 0; i < 10; ++i) { for (int j = 0; j < sub_tail_cnts[i]; ++j) { sub_tail.push_back(i + '0'); } if (i == T[0] - '0') sub_tail += T; } vector<string> hoge; if (head[0] != '0' || head.size() == 1) hoge.push_back(head); if (sub_head[0] != '0' || sub_head.size() == 1) hoge.push_back(sub_head); if (sub_tail[0] != '0' || sub_tail.size() == 1) hoge.push_back(sub_tail); sort(hoge.begin(), hoge.end()); cout << hoge[0] << endl; }