一开始觉得是数位DP,后来想不出来。 但是感觉爆搜+剪枝可以过,于是就过了。。
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; typedef long long LL; const int maxn = 50; int lim[maxn], len; LL num; void getlim(LL n) { memset(lim, 0, sizeof(lim)); len = 0; while (n) { lim[len++] = n % 10; n /= 10; } } int tmp[maxn]; LL f[maxn][maxn]; bool ok(int len,int rlen) { int l = 0, r = len - 1; while (l <= r) { if (tmp[l] != tmp[r] && r < rlen) return false; l++; r--; } return true; } LL dfs(int now, int pos, bool bound, bool first, LL num) { if (now == 0) { if (ok(pos,pos)) return num; else return 0; } bool can = false; for (int j = pos; j <= pos + now; j++) { if (ok(j, pos)) { can = true; break; } } if (!can) return 0; int m = bound ? lim[now - 1] : 9; for (int i = m; i >= 0; i--) { LL ret; int npos = pos; if (first || i) { if (pos == 0) tmp[pos] = i, npos = 1; else { if (i != tmp[pos - 1]) { tmp[pos] = i; npos = pos + 1; } else npos = pos; } } if (i) ret = dfs(now - 1, npos, bound && i == m, true, num * 10 + i); else ret = dfs(now - 1, npos, bound && i == m, false, num * 10 + i); if (ret) return ret; } return 0; } int main() { memset(f, -1, sizeof(f)); int T; scanf("%d", &T); while (T--) { scanf("%lld", &num); getlim(num - 1); printf("%lld\n", dfs(len, 0, 1, 0, 0)); } return 0; }
时间: 2024-10-12 16:31:53