• bzoj 1833 数字计数


    题目大意:

    给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次

    思路:

    不知道黄学长他们的dp都是怎么dp的

    搞神的方法太强啦

    %%%

    数位乱搞。。

    推了公式,然后每一位直接套用公式

    每一位分3种情况

    小于该位数字的直接+10的位数次方

    等于的+10的位数减一次方再加上后面几位构成数字那么多

    大于的+10的位数减一次方

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #define inf 2139062143
    10 #define ll long long
    11 using namespace std;
    12 inline ll read()
    13 {
    14     ll x=0,f=1;char ch=getchar();
    15     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    16     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    17     return x*f;
    18 }
    19 ll res[10][2],a,b;
    20 void solve(ll x,ll d)
    21 {
    22     ll k,t=1,p=0;
    23     while(10*t<=x) t*=10,p++;
    24     //cout<<x<<" "<<t<<" "<<p;
    25     while(t)
    26     {
    27         k=(x/t)%10;
    28         res[0][d]+=x/(t*10)*pow(10,p);
    29         if(!k) res[0][d]-=pow(10,p)-x%t-1;
    30         else res[k][d]+=x/(t*10)*pow(10,p)+x%t+1;
    31         for(int i=1;i<k;i++)
    32             res[i][d]+=(x/(t*10)+1)*pow(10,p);
    33         for(int i=k+1;i<=9;i++)
    34             res[i][d]+=x/(t*10)*pow(10,p);
    35         t/=10,p--;
    36     }
    37 }
    38 int main()
    39 {
    40     a=read(),b=read();
    41     solve(a-1,0);solve(b,1);
    42     for(ll i=0;i<9;i++) printf("%lld ",res[i][1]-res[i][0]);
    43     printf("%lld",res[9][1]-res[9][0]);
    44 }
    View Code
  • 相关阅读:
    linux系统——机制与策略(三)
    linux系统——机制与策略(二)
    Linux系统——机制策略(一)
    RTSP会话基本流程
    linux编程学习
    编码风格——linux内核开发的coding style
    编程风格——整洁代码的4个提示
    编程风格——五种应该避免的代码注释
    十条不错的编程观点
    代码优化概要
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/8495068.html
Copyright © 2020-2023  润新知