Mirror Number (数位dp)

来源:互联网 发布:mac pro强制重启 编辑:程序博客网 时间:2024/06/18 11:47

A number is called a Mirror number if on lateral inversion, it gives the same number i.e it looks the same in a mirror. For example 101 is a mirror number while 100 is not. 

Given two numbers a and b, find the number of mirror numbers in between them (inclusive of a and b).

Input

First line contains T, number of testcases <= 10^5.
Each testcase is described in a single line containing two numbers a and b.

0 <= a<=b <= 10^44

Output

For each test case print the number of mirror numbers between a and b in a single line.

Example

Input:30 1010 201 4Output:311


题目大概:

找出所给数字间的所有镜像数的数量,不能是252这样的回文数,必须是10801这样的数字。

思路:

和回文数的思路差不多,不过这个题数据量大一点需要字符串来村数据。

而且,这个要判断一下给出的最小的数字是不是镜像数,最后多减了,要加回来。


代码:


#include <iostream>#include <cstring>#include <cstdio>using namespace std;typedef long long ll;int dig[50] , now_dig[50],len;ll dp[50][50][2];char num[50];ll sove(int len,int sta,int flag,int first){    if(len<0) return (ll)flag;    if(dp[len][sta][flag]!=-1&&!first)return dp[len][sta][flag];    int t=(first?dig[len]:9);    ll res = 0;    for(int i=0;i<=t;i++) {        if(i==0||i==1||i==8)        {        now_dig[len]=i;        if(!i&&len==sta)        {            res+=sove(len-1,sta-1,flag,first&&i==t);        }        else if(flag&&len<(sta+1)/2)        {            res+=sove(len-1,sta,i==now_dig[sta-len ],first&&i==t);        }        else        {            res+=sove(len-1,sta,flag,first&&i==t);        }        }    }    if(!first) dp[len][sta][flag] = res;    return res;}int check(){    for(int i=0;i<=len/2;i++)    {        if(dig[i]!=0&&dig[i]!=1&&dig[i]!=8)        return 0;        if(dig[i]!=dig[len-1-i])        return 0;    }    return 1;}int main() {    int t;    scanf("%d" , &t);    memset(dp , -1 , sizeof(dp));    while(t--) {        ll ans1,ans2;        scanf("%s",num);        len=strlen(num);        for(int i=0;i<len;i++)        {            dig[i]=num[len-1-i]-'0';        }        dig[len]=0;        ans1=sove(len-1,len-1,1,1)-check();        scanf("%s",num);        len=strlen(num);        for(int i=0;i<len;i++)        {            dig[i]=num[len-1-i]-'0';        }        dig[len]=0;        ans2=sove(len-1,len-1,1,1);        printf("%lld\n" ,ans2-ans1);    }    return 0;}