HDU - 2089 不要62 (暴力或数位DP)

Description

杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。

杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。

不吉利的数字为所有含有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 <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1000000;

int n, m;
int f[maxn+5];

int check(int num) {
	while (num) {
		if (num % 10 == 4)
			return 0;
		if (num % 100 == 62)
			return 0;
		num /= 10;
	}
	return 1;
}

int cal(int num) {
	int ans = 0;
	for (int i = 1; i <= num; i++)
		if (check(i))
			f[i] = f[i-1] + 1;
		else f[i] = f[i-1];
	return ans;
}

int main() {
	memset(f, 0, sizeof(f));
	cal(maxn);
	while (scanf("%d%d", &n, &m) != EOF && n+m) {
		printf("%d\n", f[m]-f[n-1]);
	}
	return 0;
}

思路:数位DP,属于比较基础的一道,注意最后的flag的判断,这个是为了将数字本身算进去

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 1000;

/*
* dp[i][0],表示长度为i,不存在不吉利数字
* dp[i][1],表示长度为i,不存在不吉利数字,且最高位为2
* dp[i][2],表示长度为i,存在不吉利数字
*/

int n, m;
int dp[maxn][3];

void init() {
	memset(dp, 0, sizeof(dp));
	dp[0][0] = 1;
	dp[0][1] = dp[0][2] = 0;
	for (int i = 1; i < maxn; i++) {
		dp[i][0] = dp[i-1][0]*9 - dp[i-1][1];
		dp[i][1] = dp[i-1][0];
		dp[i][2] = dp[i-1][2]*10 + dp[i-1][1] + dp[i-1][0];
	}
}

int cal(int num) {
	int len = 0;
	int tmp = num;
	int bit[maxn];
	while (num) {
		bit[++len] = num%10;
		num /= 10;
	}
	bit[len+1] = 0;
	int ans = 0;
	int flag = 0;
	for (int i = len; i >= 1; i--) {
		ans += dp[i-1][2]*bit[i];
		if (flag)
			ans += dp[i-1][0]*bit[i];
		if (!flag && bit[i] > 4)
			ans += dp[i-1][0];
		if (!flag && bit[i+1] == 6 && bit[i] > 2)
			ans += dp[i][1];
		if (!flag && bit[i] > 6)
			ans += dp[i-1][1];
		if (bit[i] == 4 || (bit[i+1] == 6 && bit[i] == 2))
			flag = 1;
	}
	if (flag)
		ans++;
	return tmp - ans;
}

int main() {
	init();
	while (scanf("%d%d", &n, &m) != EOF && n+m) {
		printf("%d\n", cal(m)-cal(n-1));
	}
	return 0;
}

HDU - 2089 不要62 (暴力或数位DP),布布扣,bubuko.com

时间: 2024-10-13 11:45:03

HDU - 2089 不要62 (暴力或数位DP)的相关文章

HDU 2089 不要62(数位DP,三种姿势)

HDU 2089 不要62(数位DP,三种姿势) ACM 题目地址:HDU 2089 题意: 中文题意,不解释. 分析: 100w的数据,暴力打表能过 先初始化dp数组,表示前i位的三种情况,再进行推算 直接dfs,一遍搜一变记录,可能有不饥渴的全部算和饥渴的部分算情况,记录只能记录全部算(推荐看∑大的详细题解Orz) 代码: 1. 暴力 (以前写的) /* * Author: illuz <iilluzen[at]gmail.com> * File: 2089_bf.cpp * Create

hdu 2089 不要62 (数位dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 思路:用变量记录吉利数,和最高位为2的吉利数还有不是吉利数的个数... code: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int dp[10][3]; //dp[i][j] ,i表示位数,j表示状态<pre name="code"

[ACM] hdu 2089 不要62(数位Dp)

不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 19043    Accepted Submission(s): 6442 Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer). 杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就

HDU 4352 XHXJ&#39;s LIS (数位DP,状压)

题意: 前面3/4的英文都是废话.将一个正整数看成字符串,给定一个k,问区间[L,R]中严格的LIS=k的数有多少个? 思路: 实在没有想到字符0~9最多才10种,况且也符合O(nlogn)求LIS的特点,所以用状态压缩可以解决. 看到状态压缩的字眼基本就会做了,增加一维来保存当前LIS的状态.由于求LIS时的辅助数组d[i]表示长度为i的LIS最后一个元素,d数组是严格递增的,所以好好利用d数组的特性来设计状态压缩才是关键.压缩的状态0101可以表示:仅有0和2在数组d中,即d[1]=0,d[

HDU 5642 King&#39;s Order(数位DP)

题目链接:点击打开链接 题意:要求你生成一个合法的字符串, 由小写字母a~z组成, 相同字母相邻出现不能超过3个, 求有多少种组合. 思路:数位DP来做, 用d[i][j][k]表示处理完前i个字母, 第i-1个字母为j,已经连续出现了k次的方法数. 然后每次转移就很简单了, 继续选择字母j(if(k < 3)), 或者换其他的. 细节参见代码: #include<cstdio> #include<cstring> #include<algorithm> #inc

hdu 4722 Good Numbers(初涉数位dp)

http://acm.hdu.edu.cn/showproblem.php?pid=4722 大致题意:若一个整数的各位数字之和是10的倍数,称这个数为"good number".给出区间[A,B],求出该区间内"good number"的数的个数. 第一道数位dp,折腾了半天才明白怎么回事. 设dp[site][mod]表示到第site位(由高位向低位)前面各位数字之和对10取余为mod的数的个数,进行记忆化搜索.有两个很重要的点,首先是变量up,表示是否到达边界

hdu 4352 XHXJ&#39;s LIS (数位dp)

XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 755    Accepted Submission(s): 289 Problem Description #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then careful

HDU - 4352 - XHXJ&#39;s LIS(数位DP)

链接: https://vjudge.net/problem/HDU-4352 题意: a 到 b中一个数组成递增子序列长度等于k的数的个数 思路: 因为只有10个数,使用二进制维护一个递增序列,每次更新在注释写了. 然后正常的数位DP, Dp(i, j, k),i是位置,j是当前的递增状态,k是长度. 考虑一下前缀0,重置状态 代码: #include<bits/stdc++.h> using namespace std; typedef long long LL; const int MO

hdu 2089 不要62【数位dp】

HDU 2089 求给定区间内不含62和4的数的个数. 数位dp入门.从这里我清楚了一些数位dp的用法.比如limit是判断是否达到上界,而且需要判断(!limit)..比如若题目要求不含11的个数,举例来说:区间在[1,215],当百位开始枚举为0时,十位枚举1,个位可以取0,2~9,即dp[0][1]=9,表示枚举到个位前一位为1时满足的个数,当然此时除了1都满足.而回溯枚举到百位为2,十位为1时,由于dp[0][1]已经枚举了,可以直接返回,但此时返回时有错误的,dp[0][1]=9,而百