题解
题目让求1到n所有的回文数 n数值范围1e8就算是打表也会超时
枚举所有回文数 枚举前面4位要求是回文可以得出后面4位复杂度直接将为sqrt(n)
考虑奇偶情况中间再插入一个数字
求数字长度和位权时不要使用log10和pow复杂度很高
AC代码
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-6;
int Len(int x) //获取数字是几位
{
int cnt = x == 0;
while (x)
cnt++, x /= 10;
return cnt;
}
int Rev(int x) //反转数字
{
int v = 0;
while (x)
v = v * 10 + x % 10, x /= 10;
return v;
}
int Calc(int n) //输入n计算1到n范围内回文数量
{
int cnt = 0;
ll p[] = { 1, 10, 100, 1000, 10000, 100000 };
for (int i = 1; i < 1e4; i++) //枚举前一半 最多9999
{
int len = Len(i); //求数字是几位 log10()超级耗时!
ll rv = Rev(i); //反转后数字 当作后一半
ll v = p[len] * i + rv; //前一半+后一半 偶数长度
if (v <= n)
cnt++;
for (int j = 0; j < 10; j++) //中间在增加一位
{
v = p[len] * (i * 10 + j) + rv; //前一半+中间+后一半 奇数长度
if (v <= n)
cnt++;
}
}
return cnt + min(9, n); //上面不会计算1到9
}
int main()
{
#ifdef LOCAL
//freopen("C:/input.txt", "r", stdin);
#endif
int T;
cin >> T;
while (T--)
{
int N;
scanf("%d", &N);
printf("%d\n", Calc(N));
}
return 0;
}