ACdream 1064 完美数

Description

8是中国人很喜欢的一个数字,但是如果有3的存在就变成了38,就不是很好了。。

你能告诉我,在[L, R] 的正整数区间内,要么包含3 要么包含 8 的不同的整数有多少个么?

Input

第一行一个整数T (T ≤ 10000),代表数据的组数

对于每组数据给两个整数 L, R (1 ≤ L ≤ R ≤ 1e9)

Output

对于每组数据,给一个整数为答案。

Sample Input

3
1 100
1 3
8 8

Sample Output

34
1

1

数位dp

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int p[11],l,r;
struct abc
{
	int x,y,z;
}f[11][10];

void init()
{
	f[1][3].x=1;
	f[1][8].y=1;
	for (int i=p[1]=1;i<=10;i++) p[i+1]=10 * p[i];
	for (int i=2;i<=10;i++)
	{
		for (int j=0;j<10;j++)
		{
			if (j==3)
			{
				f[i][j].x=p[i];
				for (int k=0;k<10;k++) 
				{
					f[i][j].y+=f[i-1][k].y;
					f[i][j].z+=f[i-1][k].y;
				}
			}
			else if (j==8)
			{
				f[i][j].y=p[i];
				for (int k=0;k<10;k++) 
				{
					f[i][j].x+=f[i-1][k].x;
					f[i][j].z+=f[i-1][k].x;
				}
			}
			else 
			{
				for (int k=0;k<10;k++) 
				{
					f[i][j].y+=f[i-1][k].y;
					f[i][j].x+=f[i-1][k].x;
					f[i][j].z+=f[i-1][k].z;
				}
			}
		}
	}
}

int get(int x)
{
	int digit[11],ws=0,ans=0,f1=1,f2=1;
	while (x) digit[++ws]=x%10,x/=10;
	for (int i=ws;i;i--)
	{
		if (f1&&f2)
			for (int j=0;j<digit[i];j++)
			{
				ans+=f1*f[i][j].x+f2*f[i][j].y-(f1+f2)*f[i][j].z;
			}
		else if (f1)
			for (int j=0;j<digit[i];j++)
			{
				ans+=p[i]-f[i][j].y;
			}
		else if (f2)
			for (int j=0;j<digit[i];j++)
			{
				ans+=p[i]-f[i][j].x;
			}
		if (digit[i]==3) f2=0;
		if (digit[i]==8) f1=0;
		if (f1==0&&f2==0) break;
	}
	return ans;
}

int main()
{
	init();
	int T;
	scanf("%d",&T);
	while (T--)
	{
		scanf("%d%d",&l,&r);
		cout<<get(r+1)-get(l)<<endl;
	}
}


你可能感兴趣的:(ACdream)