[洛谷P2425]小红帽的回文数
原题传送门
这道题需要枚举。如果直接枚举会$TLE$。
考虑进制的转换:对于$> x$的进制下,一定是回文数
回文长度$2$位:设每一位为$i$,进制为$x$,则该数为$i*x+i$。反之,如果$n=i*(x+1)$,则$x$进制下$n$为回文。但要满足$i<x$,所以$x>\sqrt{n}$时适用。
当$x \leq \sqrt{n}$时暴力判断,这样复杂度降为$O(T \sqrt{n})$。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define re register 6 #define rep(i, a, b) for (re int i = a; i <= b; ++i) 7 #define repd(i, a, b) for (re int i = a; i >= b; --i) 8 #define maxx(a, b) a = max(a, b); 9 #define minn(a, b) a = min(a, b); 10 #define LL long long 11 #define INF (1 << 30) 12 13 inline LL read() { 14 LL w = 0; int f = 1; char c = getchar(); 15 while (!isdigit(c)) f = c == '-' ? -1 : f, c = getchar(); 16 while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ '0'), c = getchar(); 17 return w * f; 18 } 19 20 int T, l[40]; 21 LL n; 22 23 int main() { 24 T = read(); 25 26 rep(kase, 1, T) { 27 n = read(); 28 if (n == 2) printf("%d\n", 3); 29 else if (n <= 3) printf("%d\n", 2); 30 else { 31 register LL ans = INF; 32 for (register int i = sqrt(n-1); i; i--) 33 if (!(n - n / i * i)) { 34 ans = n / i - 1; 35 break; 36 } 37 register int range = sqrt(n), len; 38 register bool flag; 39 register LL x; 40 for (register int i = 2; i <= range; ++i) { 41 x = n; 42 len = 0; 43 while (x) { 44 l[++len] = x - x / i * i; 45 x /= i; 46 } 47 flag = 1; 48 for (register int j = 1; j <= len / 2; j++) 49 if (l[j] != l[len - j + 1]) { 50 flag = 0; 51 break; 52 } 53 if (flag) { ans = i; break; } 54 } 55 printf("%lld\n", ans); 56 } 57 } 58 59 return 0; 60 }
另外这道题比较卡常,需要一定的优化。