• 1042 数字0-9的数量(非数位dp解法)


    1042 数字0-9的数量

     
    给出一段区间a-b,统计这个区间内0-9出现的次数。
     
    比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次。
     

    输入

    两个数a,b(1 <= a <= b <= 10^18)

    输出

    输出共10行,分别是0-9出现的次数

    输入样例

    10 19

    输出样例

    1
    11
    1
    1
    1
    1
    1
    1
    1
    1


    题意很明确,
    其实只要能求的到b的就可以.
    然后用val(b) - val(a-1)就能得出结果

    我的思路是既然要求1到n的,那么每次我只计算1到n的每个数的最后一位.
    并且记录最后一位的状态变化.
    比如求2018
    那么第一次就是2018/10 = 201 2018%10 = 8
    那么从0到9每个位上就能加201, 然后 1到8都加1
    下一次就是201/10 = 20 201%10 = 1
    那么0到9每位加20*10 ,然后从1加9;
    仔细看代码就知道我的思路是什么了.

    每次都减掉最后一位数.
     1 #include <bits/stdc++.h>
     2 #define ll long long int
     3 using namespace std;
     4 ll a,b;
     5 ll an[10], bn[10];
     6 void solve(ll x,ll xn[]){
     7     ll ans = 1;
     8     ll cnt = 0;
     9     while(x){
    10         ll aa = x/10;
    11         for(int i = 0; i <= 9; i++){
    12             if(i == 0 && x%10 == 0)
    13                 xn[i] += (aa - 1)*ans;
    14             else
    15                 xn[i] += aa*ans;
    16         }
    17         ll bb = x%10;
    18         for(int i = 1; i < bb; i++){
    19             xn[i] += ans;
    20         }
    21         xn[bb] += cnt + 1;
    22         cnt = cnt + (x%10 )*ans;
    23         ans *= 10;
    24         x /= 10;
    25     }
    26 }
    27 int main(){
    28     scanf("%lld%lld", &a,&b);
    29     solve(b, bn);
    30     solve(a - 1, an);
    31     for(int i = 0; i <= 9; ++i){
    32         printf("%lld
    ",bn[i] - an[i]);
    33     }
    34     return 0;
    35 }

    数位dp

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #define LL long long
     7 using namespace std;
     8 //循环两遍,sumright-sumleft
     9 //10132 
    10 //==0:pre*after     !=0:cur*pre*对应位数+after
    11 //0 + 132 + 10*cur*100+after + 101*cur*100*10+2 +1013*1
    12 //19 1*
    13 LL ans[10];
    14 void solve(LL n,bool f)
    15 {
    16     LL cur,pre,after,temp=1,sign=f?1:-1;
    17     int cnt = 0;
    18     while((n/temp)!=0)
    19     {
    20         cur = (n/temp)%10;
    21         pre = (n/(temp*10));
    22         after = n - (n/temp)*temp;
    23         //cout<<pre<<' '<<cur<<' '<<after<<endl;
    24         int tmp = after,mul=1;
    25         while(tmp){mul*=10;tmp/=10;}
    26         //cout<<" m is "<<mul<<endl;
    27         for(int i=0;i<10;i++)
    28         {
    29             if(cur>i) ans[i]+=(pre+1)*temp*sign;
    30             if(cur<i) ans[i]+=pre*temp*sign;
    31             if(cur==i) ans[i]+=(pre*temp+after+1)*sign;
    32         }
    33         ans[0]-=temp*sign;
    34         temp*=10;
    35     }
    36 }
    37 //10+1+1
    38 int main()
    39 {
    40     LL l,r;
    41     bool f;
    42     cin>>l>>r;
    43     f = false;
    44     solve(l-1,f);
    45     f = true;
    46     solve(r,f);
    47     for(int i=0;i<10;i++)
    48     {
    49         cout<<ans[i]<<endl;
    50     }
    51     return 0;
    52 }
  • 相关阅读:
    听说高手都用记事本写C语言代码?真的假的!
    面向监狱编程,就靠它了!日子是越来越有判头了!
    如何把安静的程序员逼成话唠!
    想要自学编程?一个B站远远不够!
    2021年,学习C++还香吗?(文末赠书)!
    JVM--分代收集理论和垃圾收集算法
    Redis面试题
    基于RT1052 Aworks 使能GPIO输入功能(六)
    基于RT1052 Aworks 使能GPIO输出功能(五)
    基于RT1052 Aworks 使能ADC功能(四)
  • 原文地址:https://www.cnblogs.com/zllwxm123/p/9941998.html
Copyright © 2020-2023  润新知