http://www.lightoj.com/volume_showproblem.php?problem=1205

求区间内的回文数个数。。。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 #define ll long long
 6 ll dp[19][10],num[18];
 7 void init()
 8 {
 9     memset(dp,0,sizeof(dp));
10     dp[0][0]=1;
11     num[0]=1;
12     num[1]=10;
13     for(int i=0;i<10;i++)
14         dp[1][i]=1;
15     for(int i=2;i<19;i++){
16         num[i]=0;
17         for(int j=0;j<10;j++){
18             dp[i][j]=num[i-2];
19             //if(j!=0)
20             num[i]+=dp[i][j];
21         }
22     }
23 }
24 ll solve(ll x)
25 {
26     if(x==0)
27     return 1;
28     ll dig[20],cnt=0,ans=0;
29     while(x){
30         dig[++cnt]=x%10;
31         x/=10;
32     }
33     if(cnt==1)
34     return dig[1]+1;
35     for(int i=1;i<cnt;i++){
36         ans+=num[i];
37         if(i-2>=0)
38         ans-=num[i-2];
39     }
40     for(int i=1;i<dig[cnt];i++)
41         ans+=num[cnt-2];
42     ll tmp1=dig[cnt],tmp2=0,mul=10;
43     for(int i=cnt-1;i>cnt-cnt/2;i--){
44         for(int j=0;j<dig[i];j++){
45             if(cnt-2*(cnt-i+1)==0){
46                 ans++;
47                 continue;
48             }
49             ans+=num[cnt-2*(cnt-i+1)];
50         }
51         tmp1=tmp1+mul*dig[i];
52         mul=10*mul;
53     }
54     for(int i=cnt/2;i>0;i--)
55         tmp2=10*tmp2+dig[i];
56     if(tmp1<=tmp2){
57         if(cnt%2)
58             ans+=(dig[cnt/2+1]+1);
59         else
60             ans++;
61     }
62     else if(cnt%2){
63         ans+=dig[cnt/2+1];
64     }
65     return ans;
66 }
67 int main()
68 {
69     init();
70     int t,cas=1;
71     scanf("%d",&t);
72     while(t--){
73         ll l,r;
74         scanf("%lld%lld",&l,&r);
75         if(l>r)
76         swap(l,r);
77         printf("Case %d: %lld\n",cas++,solve(r)-solve(l-1));
78     }
79     return 0;
80 }
AC Code