zoukankan      html  css  js  c++  java
  • HDU-3555

    Bomb

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
    Total Submission(s): 11029    Accepted Submission(s): 3916


    Problem Description
    The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the time bomb. The number sequence of the time bomb counts from 1 to N. If the current number sequence includes the sub-sequence "49", the power of the blast would add one point.
    Now the counter-terrorist knows the number N. They want to know the final points of the power. Can you help them?
     
    Input
    The first line of input consists of an integer T (1 <= T <= 10000), indicating the number of test cases. For each test case, there will be an integer N (1 <= N <= 2^63-1) as the description.

    The input terminates by end of file marker.
     
    Output
    For each test case, output an integer indicating the final points of the power.
     
    Sample Input
    3
    1
    50
    500
     
    Sample Output
    0
    1
    15
    Hint
    From 1 to 500, the numbers that include the sub-sequence "49" are "49","149","249","349","449","490","491","492","493","494","495","496","497","498","499", so the answer is 15.
     
    /**
        题意:1~n之间有多少数包含49
        做法:数位dp
        ///dp[i][0] 表示当前位没有49
        ///dp[i][1] 表示当前位是以9开头
        ///dp[i][2] 表示含有49
        设sum = 0;
        对于n进行从高到低进行的扫描
        对于当前位 sum += dp[i-1][2]*mmap[i] 对于i-1满足要求的
        如果当前的位数 > 4 并且没有包含49 那么 sum += dp[i-1][1];
        如果当前已经有49了 那么 sum += dp[i-1][0] * mmap[i];
    **/
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    long long dp[20][3];
    int digit[20];
    ///dp[i][0] 表示当前位没有49
    ///dp[i][1] 表示当前位是以9开头
    ///dp[i][2] 表示含有49
    int main()
    {
        memset(dp, 0, sizeof(dp));
        dp[0][0] = 1;
        for(int i = 1; i < 20; i++) ///预处理  很好理解
        {
            dp[i][0] = dp[i - 1][0] * 10 - dp[i - 1][1];
            dp[i][1] = dp[i - 1][0];
            dp[i][2] = dp[i - 1][2] * 10 + dp[i - 1][1];
        }
        int t;
        cin >> t;
        while(t--)
        {
            int len = 0, last = 0;
            long long ans = 0;
            unsigned long long n = 0;
            cin >> n;
            n++;
            memset(digit, 0, sizeof(digit));
            while(n)
            {   digit[++len] = n % 10;
                n /= 10;
            }
            bool flag = false;
            for(int i = len; i >= 1; i--)
            {
                ans += dp[i - 1][2] * digit[i]; ///当前位的可能
                if(flag)
                {
                    ans += dp[i - 1][0] * digit[i]; ///如果已经含有49 加上I-1个不符合要求的个数
                }
                if(!flag && digit[i] > 4)   //当前位 > 4  以为前一位已经是9了所以包含49
                {
                    ans += dp[i - 1][1];
                }
                if(last == 4 && digit[i] == 9) ///包含49
                {   flag = true;
                }
                last = digit[i];    ///标记上一位
            }
            cout << ans << endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    JavaScript入门二
    JavaScript入门
    CSS样式之补充
    CSS样式之操作属性二
    隔空手势操作
    项目管理培训(2)
    uoot启动过程
    new work
    库函数开发步骤 (转)
    keil(持续更新)
  • 原文地址:https://www.cnblogs.com/chenyang920/p/4802457.html
Copyright © 2011-2022 走看看