T1 [JZOJ6315] 数字
题目描述
数据范围
分析
我叕正解写挂了,写模拟一定要仔细考虑细节啊
正解是这样说的
我是在 $n$ 串中按位数从小到大枚举数字匹配,思路和正解相似,时间复杂度相同,做法稍有不同
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <vector> #include <queue> using namespace std; #define ll long long ll inf = 1e18, p[20] = {1}; int t, n, a[20]; char s[20]; ll solve() { for (int i = 1; i <= n; i++) { ll ans = inf; for (int j = 1; j <= i; j++) { if (!a[j]) continue; ll now = 0; int len = i, k = j + i, f = 0; for (int l = 0; l < i; l++) { if (j + l <= n) now = now * 10 + a[j + l]; else now = now * 10 + a[j + l - i]; } if (j + i - 1 > n) { ll last = now % p[j + i - 1 - n]; now = now - last + (last + 1) % p[j + i - 1 - n]; } for (int l = 1; j - l; l++) if (a[j - l] != (now - 1) / p[l - 1] % 10) {f = 1; break;} if (f) continue; if (++now / p[len]) len++; while (k + len - 1 <= n) { for (int l = 0; l < len; l++) if (a[k + l] != now / p[len - l - 1] % 10) {f = 1; break;} if (f) break; k += len; if (++now / p[len]) len++; } if (f) continue; if (k > n) now--; else { for (int l = 0; k + l <= n; l++) if (a[k + l] != now / p[len - l - 1] % 10) {f = 1; break;} if (f) continue; } ans = min(ans, now); } if (ans < inf) return ans; } } int main() { scanf("%d", &t); for (int i = 1; i <= 18; i++) p[i] = p[i - 1] * 10; while (t--) { scanf("%s", s + 1); n = strlen(s + 1); for (int i = 1; i <= n; i++) a[i] = s[i] - '0'; printf("%lld\n", solve()); } return 0; }
T2 [JZOJ6313] Maja
题目描述