• HDU 2089 不要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

    首先暴力...枚举每个数,log n枚举每一位判断是否符合,复杂度n log n,爆炸

    正解~数位dp

    求解区间l - r的答案,可以转换为求1 - r和1 - (l - 1)做差

    那问题转换成了如何在区间1 - n中求解答案,问题就变得简单了

    我们用dp[i][j]表示。一个长度为i的数字,最高位数字是j,有多少个符合条件的数

    假设我们已经处理这个数字,考虑如何统计答案。

    比如我们当前在统计第i位的答案,如果这个数字第i位是k,那么,第i位是[1 , i - 1]的其他数字一定都在范围内,直接统计

    那么对于第i位等于k的数字?

    第i位等于k的数字,并不是后面的位数可以随意了,后面的数字小于给定数字的范围。所以我们可以通过枚举

    下一位的数字是什么,来统计当前位等于给定数字的数字。

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 
     6 #define RI register
     7 using namespace std;
     8 typedef long long ll;
     9 
    10 #define max(a,b) ((a) > (b) ? (a) : (b))
    11 #define min(a,b) ((a) < (b) ? (a) : (b))
    12 
    13 inline void read(int &x)
    14 {
    15     x = 0;
    16     bool flag = 0;
    17     char ch = getchar();
    18     while(ch < '0' || ch > '9')
    19     {
    20         if(ch == '-')    flag = 1;
    21         ch = getchar();
    22     }
    23     while(ch >= '0' && ch <= '9')
    24     {
    25         x = x * 10 + ch - '0';
    26         ch = getchar();
    27     }
    28     if(flag)    x *= -1;
    29 }
    30 
    31 int d[10],n,m; 
    32 int dp[10][10];
    33 
    34 void init()
    35 {
    36     dp[0][0] = 1;
    37     for(int i = 1;i <= 7;i ++)
    38         for(int j = 0;j <= 9;j ++)
    39             for(int k = 0;k <= 9;k ++)
    40                 if(j != 4 && !(j == 6 && k == 2))
    41                     dp[i][j] += dp[i - 1][k];
    42 }
    43 
    44 int solve(int n)
    45 {
    46     int len = 0;
    47     int ans = 0;
    48     while(n)
    49     {
    50         d[++ len] = n % 10;
    51         n /= 10;
    52     }
    53     d[len + 1] = 0;
    54     for(int i = len; i >= 1;i --)
    55     {
    56         for(int j = 0; j < d[i];j ++)
    57         {
    58             if(d[i + 1] != 6 || j != 2)
    59                 ans += dp[i][j];
    60         }
    61         if(d[i] == 4 || (d[i + 1] == 6 && d[i] == 2))
    62             break;
    63     }
    64     return ans;
    65 }
    66  
    67 int main()
    68 {
    69     init();
    70     while(scanf("%d%d",&m,&n) == 2)
    71     {
    72         if(n == 0 && m == 0)    break;
    73         printf("%d
    ",solve(n + 1) - solve(m));
    74     }
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    面试题 08.02. 迷路的机器人(C++)
    URI和URL的区别
    Kali Linux自定义分辨率设置
    CentOS最小化安装后配置NAT网络模式
    CentOS7.5安装及最小安装后联网配置--联网配置
    CentOS7.5安装及最小安装后联网配置--系统安装
    基数排序
    归并排序
    堆排序
    简单选择排序
  • 原文地址:https://www.cnblogs.com/illyaillyasviel/p/7711043.html
Copyright © 2020-2023  润新知