zoukankan      html  css  js  c++  java
  • 数位DP入门(A

    题目链接:https://cn.vjudge.net/contest/278036#problem/A

    具体思路:对于给定的数,我们按照位数进行运算,枚举每一位上可能的数,在枚举的时候需要注意几个条件,第一个,当前位上不能是4,第二如果前一位是6的话,当前的这一位不能是2,然后注意这个条件就可以了。

    AC代码:

    #include<iostream>
    #include<stack>
    #include<iomanip>
    #include<cmath>
    #include<queue>
    #include<stdio.h>
    #include<map>
    #include<string>
    #include<cstring>
    using namespace std;
    # define ll long long
    const int maxn = 1e6+100;
    int dig[10];
    int dp[10];
    int dfs(int len,bool fp,bool is6)//fp是用来判断是不是首位上的最大值,is6是用来判断当前的上一位是不是6
    {
        if(len==0)
            return 1;
        if(!fp&&dp[len][is6]!=-1)
            return dp[len][is6];
        int ans=0,fmax=fp?dig[len]:9;//如果是首位的话,只能枚举到首位,不是的话,0-9都是可以的。
        for(int i=0; i<=fmax; i++)
        {
            if((i==4)||(is6&&i==2))
                continue;
            ans+=dfs(len-1,fp&&i==fmax,i==6);
        }
        if(!fp)
            dp[len][is6]=ans;
        return ans;
    }
    int fac(int n)
    {
        memset(dp,-1,sizeof(dp));
        int num=0;
        while(n)//把每一位取出来
        {
            dig[++num]=n%10;
            n/=10;
        }
        return dfs(num,1,0);
    }
    int cal(int n,int m)
    {
        return fac(m)-fac(n);
    }
    int main()
    {
        int l,r;
        while(~scanf("%d %d",&l,&r)&&(l+r))
        {
            printf("%d
    ",cal(l-1,r));
        }
        return 0;
    }
    

    B题:

    题目链接:https://cn.vjudge.net/contest/278036#problem/B

    题目大意:让你求出1-n有多少个49,然后输出来。

    具体思路:我们可以先把不满足情况的找出来,然后再总总数去减去这个数就可以了,但是要注意一点,再所有的不满足情况中,0也算是不满足的,但是要求n是大于1的,所以需要最终结果加上1. 

    #include<iostream>
    #include<cstring>
    #include<stack>
    #include<stdio.h>
    #include<iomanip>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    # define ll long long
    const int maxn = 20+5;
    ll dig[maxn],dp[maxn][maxn];
    ll dfs(ll len,bool fp,bool is4)
    {
        if(!len)
            return 1;
        if(!fp&&dp[len][is4]!=-1)
            return dp[len][is4];
        ll ans=0,fmax=fp?dig[len]:9;
        for(int i=0; i<=fmax; i++)
        {
            if(i==9&&is4)
                continue;
            ans+=dfs(len-1,fp&&i==fmax,i==4);//这个地方的fp需要根据两个变量进行比较,上一位和当前的这一位。
        }
        dp[len][is4]=ans;
        return ans;
    }
    ll cal(ll t)
    {
        memset(dp,-1,sizeof(dp));
        int num=0;
        while(t)
        {
            dig[++num]=t%10;
            t/=10;
        }
        return dfs(num,1,0);
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            ll n;
            scanf("%lld",&n);
            printf("%lld
    ",n-cal(n)+1);
        }
        return 0;
    }
    
  • 相关阅读:
    反射
    jQuery之Dom操作
    Jquery学习开篇
    c#构造函数
    c#之委托
    DataX启动步骤解析
    JobContainer
    DataX 启动配置
    DataX源码分析(2)
    DataX源码分析(1)
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262738.html
Copyright © 2011-2022 走看看