• 小米oj 找小"3"(数位dp)


    - 找小“3”

    序号:#40难度:困难时间限制:1000ms内存限制:10M

    描述

    给定一个奇数n,可得到一个由从1到n的所有奇数所组成的数列,求这一数列中数字3所出现的总次数。例如当n=3时,可得到奇数列:1,3,其中有一个数字3,故可得1

    输入

    一个奇数。表示n,0<n<9999999999。

    输出

    一个整数,表示从 1 到 n 的奇数列中,数字 3 出现的次数。

    输入样例

    1
    3
    35

     复制样例

    输出样例

    0
    1
    7
    #include<iostream>
    #include<string.h>
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int bit[15];
    ll n;
    ll ans;
    ll dp[15];
    ll mypow(ll a,ll b)
    {
        if(b==0)return 2;
        ll ret=1;
        while(b--)ret*=a;
        return ret;
    }
    ll get(ll p)
    {
        if(p==0)return 1;
        ll tmp=1;ll res=0;
        for(ll i=1;i<=p;i++)
        {
            res+=bit[i]*tmp;
            tmp*=10;
        }
        return res;
    }
    ll dfs(ll pos,bool flag)
    {
        if(flag&&dp[pos]!=-1)return dp[pos];
        if(pos==0)return 0;
        ll x=flag?9:bit[pos];
        ll res=0;
        for(ll i=0;i<=x;i++)
        {
            if(i==3){
                if(flag||i<x){res+=mypow(10,pos-1)/2;}
                else {
                    res+=(get(pos-1)+1)/2;
                }
               res+=dfs(pos-1,flag||i<x);
            }
            else {
               res+=dfs(pos-1,flag||i<x);
            }
        }
        if(flag)dp[pos]=res;
        return res;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%lld",&n))
        {
            memset(dp,-1,sizeof(dp));
            int cnt=0;
            while(n)
            {
                bit[++cnt]=n%10;
                n/=10;
            }
            ans=dfs(cnt,0);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    穷举 迭代 while
    for 循环
    switch case
    if else 语句
    数据类型
    语句的输入、输出
    控件——DataGridview
    mysql-bin.000001文件的来源及处理方法
    /var/log目录下的20个Linux日志文件功能详解
    CountDownLatch
  • 原文地址:https://www.cnblogs.com/linruier/p/9948618.html
Copyright © 2020-2023  润新知