zoukankan      html  css  js  c++  java
  • hdu-2089 不要62

    不要62

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

    Problem 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
     
    Recommend
    lcy   |   We have carefully selected several similar problems for you:  2094 2090 2091 2093 2092 
     
    Solution
    没有怎么做过数位dp,感觉好难啊
    看到一篇讲得很好的博客
    计算区间[l,r],可以转化为[0,r]-[0,l-1]
    从最高位开始搜索,搜索的时候记录wi(当前位) , pre(上一位是多少) , lim(上一位是否达到上限)
    由于62不能在数中出现,所以如果pre==6,当前位就不能为2,
    不能出现4的限制在枚举的时候直接跳过就可以了。
    如果上一位达到l(r)的上限了,那么这一位也只能取到l(r)的上限,否则可以取0~9的任何数。
    并且如果上一位达到l(r)的上限了,说明这一位也被限制了,那么就不能用这个时候得到的答案去更新dp数组,因为这并不是一般情况(一般情况应该是0~9都可以取的)
    同理,如果dp值已经被算过了,也不能直接用,因为dp值里存的是一般情况的答案。
    在这道题中前导0是合法的,相当于这个数没有那一位。
    有一个小小的优化,如果是多组数据,把dp数组清0的语句放在多组数据的外面(因为区间并不能改变每个数的性质)。
     
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    int dp[11][2],a[11];
    inline int read()
    {
    	register int ans=0,f=1;char ch=getchar();
    	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    	while(isdigit(ch)) {ans=ans*10+ch-'0';ch=getchar();}
    	return ans*f;
    }
    int dfs(int wi,bool pre,bool lim)
    {
    	int ans=0;
    	if(wi<1) return 1;
    	if(!lim&&dp[wi][pre]!=-1)
    	  return dp[wi][pre];
    	int o=lim? a[wi]:9;
    	for(int i=0;i<=o;i++)
    	  if(i!=4&&(!pre||i!=2))
    	    ans+=dfs(wi-1,i==6,lim&&i==a[wi]);
    	if(!lim) dp[wi][pre]=ans;
    	return ans;
    }
    int sol(int x)
    {
    	int w=0;
    	while(x)
    	{
    		a[++w]=x%10;
    		x/=10;
    	}
    	return dfs(w,0,1);
    }
    int main()
    {
    	int l,r;
    	l=read();r=read();
    	memset(dp,-1,sizeof(dp));
    	while(l&&r)
    	{
    		printf("%d
    ",sol(r)-sol(l-1));
    		l=read();r=read();
    	}
    	return 0;
    }
  • 相关阅读:
    Hamler 0.2 正式发布
    Xamarin.Forms 解决ListView高度问题
    Xamarin.Forms中DependencyService的使用
    Xamarin.Forms Android 底部导航栏
    修改UITabBar样式 TintColor 和 Selected Tab Images in Xamarin.Forms iOS
    Xamarin.iOS中使用MvvmLight框架
    Xamarin.iOS 代码中添加约束练习
    Xamarin.Android 手势密码
    UWP 手势密码实现
    Xamarin.iOS 手势密码
  • 原文地址:https://www.cnblogs.com/charlotte-o/p/7608052.html
Copyright © 2011-2022 走看看