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 ",cas++,solve(r)-solve(l-1)); 78 } 79 return 0; 80 }