首页 > 代码库 > [HDU2089]不要62

[HDU2089]不要62

[HDU2089]不要62

试题描述

杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。

输入

输入的都是整数对n、m(0<n≤m<1000000),如果遇到都是0的整数对,则输入结束。

输出

对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。

输入示例

1 100
0 0

输出示例

80

数据规模及约定

见“输入

题解

106 直接处理前缀和即可。。。强行练一波数位 dp。。

前缀和版。。。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;

int read() {
	int x = 0, f = 1; char c = getchar();
	while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = getchar(); }
	while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = getchar(); }
	return x * f;
}

bool has62(int x) {
	while(x) {
		if(x % 100 == 62) return 1;
		x /= 10;
	}
	return 0;
}
bool has4(int x) {
	while(x) {
		if(x % 10 == 4) return 1;
		x /= 10;
	}
	return 0;
}

#define maxn 1000010
int f[maxn];

int main() {
	f[0] = 0;
	for(int i = 1; i <= maxn - 10; i++) f[i] = f[i-1] + (!has62(i) && !has4(i));
	int n = read(), m = read();
	while(n || m) {
		printf("%d\n", f[m] - f[n-1]);
		n = read(); m = read();
	}
	
	return 0;
}

数位 dp 版。。。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;

int read() {
	int x = 0, f = 1; char c = getchar();
	while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = getchar(); }
	while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = getchar(); }
	return x * f;
}

int f[7][11];

int num[11], cnt;
int sum(int x) {
	cnt = 0;
	int tmp = x;
	while(x) num[++cnt] = x % 10, x /= 10;
	int ans = 0; bool ok = 1;
	for(int i = cnt; i; i--) {
		for(int j = 0; j < num[i]; j++)
			if(i < cnt && num[i+1] == 6 && j == 2) ;
			else ans += f[i][j];
		if(num[i] == 4 || (i < cnt && num[i+1] == 6 && num[i] == 2)) {
			ok = 0; break;
		}
	}
	ans += ok;
//	printf("%d %d\n", tmp, ans);
	return ans;
}

int main() {
	f[0][0] = 1;
	for(int i = 0; i < 6; i++)
		for(int j = 0; j <= 9; j++) if(f[i][j]) {
			for(int k = 0; k <= 9; k++)
				if(k != 4 && !(k == 6 && j == 2))
					f[i+1][k] += f[i][j];
//			printf("%d %d: %d\n", i, j, f[i][j]);
		}
	
	int l = read(), r = read();
	while(l || r) {
		printf("%d\n", sum(r) - sum(l - 1));
		l = read(); r = read();
	}
	
	return 0;
}

 

[HDU2089]不要62