A palindromic number or numeral palindrome is a 'symmetrical' number like 16461 that remains the same when its digits are reversed. In this problem you will be given two integers i j, you have to find the number of palindromic numbers between i and j (inclusive).
Input starts with an integer T (≤ 200), denoting the number of test cases.
Each case starts with a line containing two integers i j (0 ≤ i, j ≤ 1017).
For each case, print the case number and the total number of palindromic numbers between i and j (inclusive).
4
1 10
100 1
1 1000
1 10000
Case 1: 9
Case 2: 18
Case 3: 108
Case 4: 198
分析:
求区间内回文数的个数,问题关键在于新增加一个数组,用来记录前一半选了的数字
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[20],t[20];
long long dp[20][20][2];
long long dfs(int pos,int sta1,int s,int limit)
{
if(!sta1)
return s;
if(!limit && dp[pos][sta1][s] != -1)
return dp[pos][sta1][s];
int n = limit?a[sta1]:9;
long long ans = 0;
for(int i=0;i<=n;i++)
{
t[sta1] = i;
if(pos == sta1 && i == 0)
ans+= dfs(pos-1,sta1-1,s,limit&&i==n);
else if(s && sta1 <= (pos+1)/2)
ans += dfs(pos,sta1-1,t[pos-sta1+1]==i,limit&&i==n);
else
ans += dfs(pos,sta1-1,s,limit&&i==n);
}
if(!limit)
dp[pos][sta1][s] = ans;
return ans;
}
long long cal(long long x)
{
int pos = 0;
while(x)
{
a[++pos] = x % 10;
x /= 10;
}
return dfs(pos,pos,1,1);
}
int main()
{
int T;
scanf("%d",&T);
memset(dp,-1,sizeof(dp));
int cas = 1;
while(T--)
{
long long a,b;
scanf("%lld%lld",&a,&b);
if(a>b)swap(a,b);
printf("Case %d: %lld\n",cas++,cal(b) - cal(a-1));
}
return 0;
}