您的位置:首页 > 其它

Mirror Number (数位dp)

2017-11-12 23:21 218 查看
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:
3
0 10
10 20
1 4

Output:
3
1
1


题目大概:

找出所给数字间的所有镜像数的数量,不能是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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息