zoukankan      html  css  js  c++  java
  • HDU 2089 不要62(数位DP)

    不要62

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 11833    Accepted Submission(s): 3691


    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
     
    Author
    qianneng
     
    Source
     
    Recommend
    lcy
     
     
     
    简单的数位DP;
    注释在代码中
    /*
     * HDU 2089
     * 求一个区间内,不出现4和连续的62的数的个数。
     * 这题可以暴力打表。
     * 数位DP也可以做。
     *
     */
    
    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    #include <string.h>
    using namespace std;
    int dp[10][3];
    /*
     * dp[i][0],表示长度为i,不存在不吉利数字
     * dp[i][1],表示长度为i,不存在不吉利数字,且最高位为2
     * dp[i][2],表示长度为i,存在不吉利数字
     */
    void init()
    {
        dp[0][0]=1;dp[0][1]=0;dp[0][2]=0;
        for(int i=1;i<=6;i++)
        {
            dp[i][0]=dp[i-1][0]*9-dp[i-1][1];//在最高位加上除4以外的9个数字,但要减掉2之前加上6
            dp[i][1]=dp[i-1][0];//在不含不吉利数字的最高位加上2
            dp[i][2]=dp[i-1][2]*10+dp[i-1][0]+dp[i-1][1];
            //在已有不吉利数字前加任意数字,或者无不吉利数字的最高位加4,或者在2前面加6
        }
    }
    int bit[10];
    int solve(int n)
    {
        int len=0;
        int tmp=n;
        while(n)
        {
            bit[++len]=n%10;
            n/=10;
        }
        bit[len+1]=0;
        int ans=0;
        bool flag=false;
        for(int i=len;i>=1;i--)
        {
            ans+=dp[i-1][2]*bit[i];
            if(flag)//高位已经出现4或者62,后面随意
                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=true;
        }
        if(flag)ans++;//这个数本身
        return tmp-ans;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        init();
        int n,m;
        while(scanf("%d%d",&n,&m)==2)
        {
            if(n==0 && m==0)break;
            printf("%d\n",solve(m)-solve(n-1));
        }
        return 0;
    }
     
     
     
    人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
  • 相关阅读:
    UVA 11925 Generating Permutations 生成排列 (序列)
    UVA 1611 Crane 起重机 (子问题)
    UVA 11572 Unique snowflakes (滑窗)
    UVA 177 PaperFolding 折纸痕 (分形,递归)
    UVA 11491 Erasing and Winning 奖品的价值 (贪心)
    UVA1610 PartyGame 聚会游戏(细节题)
    UVA 1149 Bin Packing 装箱(贪心)
    topcpder SRM 664 div2 A,B,C BearCheats , BearPlays equalPiles , BearSorts (映射)
    UVA 1442 Cave 洞穴 (贪心+扫描)
    UVA 1609 Foul Play 不公平竞赛 (构(luan)造(gao)+递归)
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3052424.html
Copyright © 2011-2022 走看看