<题目链接>
不要62
Problem Description
杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。
Input
输入的都是整数对n、m(0<n≤m<1000000),如果遇到都是0的整数对,则输入结束。
Output
对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。
Sample Input
1 100
0 0
Sample Output
80
# include<cstdio> # include<iostream> # include<cstring> using namespace std; int dp[10][10];//dp[i][j]表示的是以j开头的i位数中,不含4和62的个数 int digit[10]; void init() //先打一张表,预先算出题目可能需要的所有dp[i][j]; { memset(dp, 0, sizeof(dp)); dp[0][0] = 1; for (int i = 1; i <= 7; i++) { for (int j = 0; j <= 9; j++) {//枚举第i位 for (int k = 0; k <= 9; k++) {//枚举第i-1位 if (j != 4 && (!(j == 6 && k == 2))) { dp[i][j] = dp[i][j] + dp[i - 1][k]; } } } } } int sum(int n) //求的是小于n的数字有多少个,从下面的j<digit[i]可以看出 { int len = 0; int ans = 0; while (n != 0) { digit[++len] = n % 10; n = n / 10; } digit[len + 1] = 0; for (int i = len; i >= 1; i--) //i表示枚举的数字的位数,j表示,所有小于n的各位数为起点的数的数量 { for (int j = 0; j < digit[i]; j++) { if (j != 4 && (!(digit[i + 1] == 6 && j == 2))) //注意这里是i+1,因为digit内是按位数从小到大的顺序存的 { ans += dp[i][j]; } } if (digit[i] == 4 || (digit[i] == 2 && digit[i + 1] == 6)) { break; } } return ans; } int main(void) { int n, m; while (cin >> n >> m, n || m) { init(); printf("%d\n", sum(m+1) - sum(n)); } return 0; }
2018-07-29