题意:给你一个区间[l, r],问你这个区间中有多少回文数。l, r的范围是long long 级别的。
解题思路:数位dp,dp[i][j][k]表示i位数,前当前是j位,k = 1表示当前回文的回文数数量就行
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 100;
int num[maxn];
int temp[maxn];
LL dp[maxn][maxn][2];
LL dfs(int start, int now, int status, int limit)
{
if(dp[start][now][status] != -1 && !limit) return dp[start][now][status];
if(now < 1) return status;
int up = limit ? num[now] : 9;
LL ans = 0;
for(int i = 0; i <= up; i++)
{
temp[now] = i;
if(start == now && i == 0) ans += dfs(start - 1, now - 1, status, (i == up) && limit);
else if(now <= (start + 1) / 2 && status) ans += dfs(start, now - 1, temp[start - now + 1] == temp[now], (i == up) && limit);
else ans += dfs(start, now - 1, status, (i == up) && limit);
}
if(!limit) dp[start][now][status] = ans;
return ans;
}
LL solve(LL x)
{
int len = 0;
while(x)
{
num[++len] = x % 10;
x /= 10;
}
return dfs(len, len, 1, 1);
}
int main()
{
memset(dp, -1, sizeof(dp));
int T;
int Case = 1;
scanf("%d", &T);
while(T--)
{
LL l, r;
scanf("%lld%lld", &l, &r);
if(l > r) swap(l, r);
printf("Case %d: %lld\n", Case++, solve(r) - solve(l - 1));
}
return 0;
}