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;
	}
}


温故而知新

#include<set>
#include<map>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<bitset>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define rep(i,j,k) for (int i = j; i <= k; i++)
#define per(i,j,k) for (int i = j; i >= k; i--)
#define loop(i,j,k) for (int i = j;i != -1; i = k[i])
#define lson x << 1, l, mid
#define rson x << 1 | 1, mid + 1, r
#define fi first
#define se second
#define mp(i,j) make_pair(i,j)
#define pii pair<int,int>
using namespace std;
typedef long long LL;
const int low(int x) { return x&-x; }
const double eps = 1e-8;
const int INF = 0x7FFFFFFF;
const int mod = 10000;
const int N = 20;
const int read()
{
	char ch = getchar();
	while (ch<'0' || ch>'9') ch = getchar();
	int x = ch - '0';
	while ((ch = getchar()) >= '0'&&ch <= '9') x = x * 10 + ch - '0';
	return x;
}
int T, l, r, f[10][3], a[N];

int solve(int x)
{
	int tot = 0;
	if (x == 0) return 0;
	while (x) a[++tot] = x % 10, x /= 10;
	int f1 = 0, f2 = 0, ans = 0;
	per(i, tot, 1)
	{
		if (f1&&f2) return ans;
		rep(j, 0, a[i] - 1)
		{
			if (f1) ans += (j != 8)*(f[i - 1][0] + f[i - 1][1]);
			if (f2) ans += (j != 3)*(f[i - 1][0] + f[i - 1][2]);
			if (!f1 && !f2)
			{
				ans += (j == 3 || j == 8)*f[i - 1][0] + (j != 8)*f[i - 1][1] + (j != 3)*f[i - 1][2];
			}
		}
		f1 |= a[i] == 3;
		f2 |= a[i] == 8;
	}
	return ans + (f1 + f2 == 1);
}

int main()
{
	f[0][0] = 1;
	rep(i, 1, 10)
	{
		rep(j, 0, 9)
		{
			f[i][0] += (j != 3 && j != 8) * f[i - 1][0];
			f[i][1] += (j == 3) * f[i - 1][0] + (j != 8) * f[i - 1][1];
			f[i][2] += (j == 8) * f[i - 1][0] + (j != 3) * f[i - 1][2];
		}
	}
	T = read();
	while (T--)
	{
		scanf("%d%d", &l, &r);
		printf("%d\n", solve(r) - solve(l - 1));
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值