zoukankan      html  css  js  c++  java
  • 【HDU3652】B-number 数位DP

      B-number

    Problem Description
    A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- string "13" and can be divided by 13. For example, 130 and 2613 are wqb-numbers, but 143 and 2639 are not. Your task is to calculate how many wqb-numbers from 1 to n for a given integer n.
    Input
    Process till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).
    Output
    Print each answer in a single line.
    Sample Input
    13
    100
    200
    1000
    Sample Output
    1
    1
    2
    2
    题意:求n以内所有能被13整除且数字里包含13的数的个数
    题解:数位DP,用f[i][j][k]表示有i位,最高位为j,对13取模等于k,且数字里包含13的数的个数,g[i][j][k]表示有i位,最高位为j,对13取模等于k,且数字里包含13的数的个数。
      然后一位一位判断就可以了。
    代码
    #include <stdio.h>
    #include <string.h>
    int n,m;
    int v[20];
    int f[12][10][13],g[12][10][13],t[12];
    int main()
    {
        int i,j,k,l,ans,rem,x;
        t[1]=1;
        for(i=2;i<=10;i++)    t[i]=t[i-1]*10;
        for(i=0;i<=9;i++)    g[1][i][i]=1;
        for(i=2;i<=10;i++)
        {
            for(j=0;j<=9;j++)
            {
                for(k=0;k<=9;k++)
                {
                    for(l=0;l<=12;l++)
                    {
                        if(j==1&&k==3)
                        {
                            f[i][j][l]+=(j*t[i]+(k+1)*t[i-1]-1-l)/13-(j*t[i]+k*t[i-1]-1-l)/13;
                        }
                        else
                        {
                            f[i][j][l]+=f[i-1][k][((l-j*t[i])%13+13)%13];
                            g[i][j][l]+=g[i-1][k][((l-j*t[i])%13+13)%13];
                        }
                    }
                }
            }
        }
        while(scanf("%d",&n)!=EOF)
        {
            memset(v,0,sizeof(v));
            rem=m=ans=0;  //此时答案的后i位对13取模应该等于rem
            x=n;
            while(x)
            {
                v[++m]=x%10;
                x/=10;
            }
            for(i=m;i>=1;i--)
            {
                for(j=0;j<v[i];j++)    ans+=f[i][j][rem];
                if(v[i]>3&&v[i+1]==1)
                {
                    ans+=g[i][3][rem];
                }
                if(v[i]==3&&v[i+1]==1)
                {
                    ans+=n/13-(n/t[i]*t[i]-1)/13;
                    break;
                }
                rem=((rem-v[i]*t[i])%13+13)%13;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }

    | 欢迎来原网站坐坐! >原文链接<

  • 相关阅读:
    PATA 1071 Speech Patterns.
    PATA 1027 Colors In Mars
    PATB 1038. 统计同成绩学生(20)
    1036. 跟奥巴马一起编程(15)
    PATA 1036. Boys vs Girls (25)
    PATA 1006. Sign In and Sign Out (25)
    读取web工程目录之外的图片并显示
    DOS命令
    java连接oracle集群
    servlet
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6155729.html
Copyright © 2011-2022 走看看