链接
传送门
题意
原本有一个数字组成的字符串,现在给出将原字符串的长度附加在字符串后打乱的字符串,和原字符串的一个子串。输出字典序最小的原字符串,不允许有前导零。
思路
设原字符串的子串为\(s0\),在原字符串中去掉\(s0\)之后的字符串为\(s1\),我们可以构造出两个字符串,最后比较输出。
最后输出\(min(ans1, ans2)\),注意判断前导零。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <vector> #include <queue> using namespace std;
const int maxn = 1000010; const int inf = 0x3f3f3f3f; int cnt[10], len; char s[maxn]; string ans1, ans2;
int getLen(int k) { int res = 0; while (k) { k /= 10; ++res; } return res == 0 ? 1 : res; }
bool check(char c) { for (int i = 0; i < len; ++i) { if (c != s[i]) { return c > s[i]; } } return false; }
int main() { scanf("%s", s); while (s[len]) { ++cnt[s[len] - '0']; ++len; } for (int i = 1; i <= 7; ++i) { int rm = len - i; if (getLen(rm) == i) { len = rm; while (rm) { --cnt[rm % 10]; rm /= 10; } break; } } scanf("%s", s); len = 0; while (s[len]) { --cnt[s[len] - '0']; ++len; } ans2 += s; int flag = -1; for (int i = 1; i < 10; ++i) { if (cnt[i] > 0) { ans1 += char(i + '0'); --cnt[i]; flag = i; break; } } bool ok = false; for (int i = 0; i < 10; ++i) { if (flag == i) { ans2 += char(i + '0'); } if (cnt[i] > 0) { char c = i + '0'; if (!ok && check(c)) { ans1 += s; ok = true; } while (cnt[i] > 0) { ans1 += c; ans2 += c; --cnt[i]; } } } if (flag == -1) { puts(ans2.c_str()); return 0; } if (!ok) { ans1 += s; } puts(ans2[0] != '0' && ans2 < ans1 ? ans2.c_str() : ans1.c_str()); return 0; }
|