题目大意:给定区间问区间内有多少数是回文数;
题目解析:因为给定长度,其实就已经知道看了他的对称中心,所以从前往后dfs,判断前i位的时候,要判断后面是否可以取到,如果不可以去到,那么后面那位的前一位就必须小于limit,所以dfs要多一个变量ok;
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
ll dp[50][50];
int num[50];
ll dfs(int pos,int l,bool ok,bool limit)
{
int r=pos-l+1;
if(r>l) return ok||(!limit);
if(!limit&&dp[pos][l]!=-1) return dp[pos][l];
int u=limit?num[l]:9;
ll ans=0;
for(int i=(l==pos)?1:0;i<=u;i++)
{
if(ok&&num[r]>=i) ans+=dfs(pos,l-1,true,limit&&i==u);
else if(!ok&&num[r]>i) ans+=dfs(pos,l-1,true,limit&&i==u);
else ans+=dfs(pos,l-1,false,limit&&i==u);
}
if(!limit) return dp[pos][l]=ans;
return ans;
}
ll solve(ll n)
{
if(n==0) return 1;
if(n<0) return 0;
int cnt=0;
while(n)
{
num[++cnt]=n%10;
n/=10;
}
ll ans=1;
for(int i=cnt;i>=1;i--)
ans+=dfs(i,i,true,i==cnt);
return ans;
}
int main()
{
ll a,b;
memset(dp,-1,sizeof(dp));
int cas,c=1;
scanf("%d",&cas);
while(cas--)
{
scanf("%lld%lld",&a,&b);
if(a>b)
{
ll t=a;
a=b;
b=t;
}
printf("Case %d: ",c++);
printf("%lld\n",solve(b)-solve(a-1));
}
return 0;
}