• Bomb


    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.
     
     
     
    开始看不懂题的时候可以看一下后面的举例子,做题的时候没有看到例子好久才看懂的,说多了都是泪。
     

    题目大意:

      给一个数字n,范围在1~2^63-1,求1~n之间含有49的数字有多少个。

    经典的数位dp,参考了大腿的代码:http://www.cnblogs.com/luyi0619/archive/2011/04/29/2033117.html

    状态转移:

      dp[i][0]代表长度为 i 并且不含有49的数字的个数;

      dp[i][1]代表长度为 i 并且不含有49,但是最高位是9的数字的个数;

      dp[i][2]代表长度为 i 并且含有49的数字的个数。

      数组 a[i] 从低位到高位存储 n 的每一位数字。

    详解参考:http://www.cnblogs.com/liuxueyang/archive/2013/04/14/3020032.html

    代码如下:

    #include<iostream>
    #include <string.h>
    #include <stdio.h>
    using namespace std;
    typedef long long ll;
    ll dp[25][3];
    
    
    void init()
    {
        dp[0][0] = 1; //表示位数为i的无49的个数; 等于1是为首位为9,位数为1的数服务;
        dp[0][1] = 0; //表示位数为i的无49的个数但最高位为9的个数;
        dp[0][2] = 0; //表示位数为i的含有49的个数;
        for(int i = 1; i < 25; i++)
        {
            dp[i][0] = dp[i - 1][0] * 10 - dp[i - 1][1]; //减去最高位为9的情况;
            dp[i][1] = dp[i - 1][0];                     //最高位加9的个数
            dp[i][2] = dp[i - 1][2] * 10 + dp[i - 1][1]; //加上没含49但最高位是9的个数(加上4就成49了);
        }
    }
    ll solve(ll n)
    {
        ll ans = 0;
        bool vis = false;
        int bit[25],tot = 0;
        while(n)
        {
            bit[++tot] = n % 10;
            n /= 10;
        }
    bit[tot + 1] = 0;
        for(int i = tot; i >= 1; i--)
        {
            ans += dp[i - 1][2] * bit[i];
            if(vis) ans += bit[i] * dp[i - 1][0]; // 这一步和下一步要细心体会其中的高深之处,看了kuangbin大神的代码好久才明白这个道理;
            else if(bit[i] > 4) ans += dp[i - 1][1]; //如果n本身已经含有49了就不用考虑是否最高位为9了,直接加上没49的个数,因为n含了49
            if(bit[i + 1] == 4 && bit[i] == 9) vis = true;
        }
        if(vis) ans++; //如果n本身也包含49,则要加1;
        return ans;
    }
    
    
    int main()
    {
        ll n;
        int t;
        init();
        scanf("%d", &t);
        while(t--)
        {
            scanf("%lld",&n);
            printf("%lld
    ",solve(n));
        }
        return 0;
    }
    

      

     
  • 相关阅读:
    Android 从零搭建简单MVP Demo
    Ubuntu 16.04 安装wine QQ
    Android 根据字符串动态获取资源ID
    Android 个推 踩坑小结
    Android Studio 查看手机CPU信息
    J2EE 项目本地发布路径及修改
    Cucumber 安装
    [译] 第三十天:Play Framework
    [译] 第二十九天:Yeoman Chrom Generator
    [译] 第二十八天:Java开发者的OpenShift Eclipse 集成
  • 原文地址:https://www.cnblogs.com/llfj/p/5768111.html
Copyright © 2020-2023  润新知