• O-Bomb(数位dp)


    Bomb

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


    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.
     
     
    //题意 t 组数据,在 1- n 中出现了49的数据个数,n 很大,2^63-1 , 遍历肯定不行。
     
    //听说这是数位dp的一道水题,这也是水题吗,我服了
    自己想了一阵,只想到了一点点。看了别人的也看了很久,才明白,这篇博客非常详细,我就不赘述了,认真看一定能看懂。
    我的与他的dp数组有细微差别,因为我自己理解了写了一遍,稍微注意一下。
     
    代码 15ms
     
     1 #include <stdio.h>
     2 #include <string.h>
     3 
     4 __int64 dp[25][3];
     5 //dp[i][0]   含49,数的个数
     6 //dp[i][1] 不含49,但首位是9的数的个数
     7 //dp[i][2] 不含49,数的个数(包含了首位是9的数的个数)
     8 void Init()
     9 {
    10     dp[0][2]=1;
    11     for (int i=1;i<=24;i++)
    12     {
    13         dp[i][0]=dp[i-1][0]*10+dp[i-1][1];
    14         dp[i][1]=dp[i-1][2];
    15         dp[i][2]=dp[i-1][2]*10-dp[i-1][1];
    16     }
    17 }
    18 
    19 __int64 solve(__int64 n)
    20 {
    21     __int64 a[25],len=0;
    22 
    23     while (n)
    24     {
    25         a[++len]=n%10;
    26         n/=10;
    27     }
    28     a[len+1]=0;
    29 
    30     __int64 ans=0;
    31     int flag=0;
    32 
    33     for (int i=len;i>0;i--)
    34     {
    35         ans+=dp[i-1][0]*a[i];
    36         if (flag)           //前面有49就所有情况都是49数了
    37             ans+=dp[i-1][2]*a[i];
    38         if (!flag&&a[i]>4)  //加上4  9... 的情况
    39             ans+=dp[i-1][1];
    40         if (a[i]==9&&a[i+1]==4)//判断是不是 49 
    41             flag=1;
    42     }
    43     return ans;
    44 }
    45 
    46 int main()
    47 {
    48     int t;
    49     __int64 n;
    50     Init();
    51     scanf("%d",&t);
    52     while (t--)
    53     {
    54         scanf("%I64d",&n);
    55         printf("%I64d
    ",solve(n+1));//因为函数功能是 (0,n) 区间的49数,题目要求的是[1,n],所以+1
    56     }
    57     return 0;
    58 }
    View Code
     
  • 相关阅读:
    记录——framework探测定位程序集与core探测定位程序集
    C# 特定框架适用特定代码
    python读取excel代码
    时间比较
    ORA 01791错误
    MongoDB.1什么是MongoDB
    Mayatis 异常之result maps collection already contains value...
    怎样做好黄焖鸡
    关于foreach
    C#之out,ref关键字
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/5753732.html
Copyright © 2020-2023  润新知