洛谷 P1980 计数问题

该博客介绍了一种解决计数问题的方法,具体是在1到n的整数范围内统计数字x(0≤x≤9)出现的次数。通过分析个位、十位等不同位数上的数字出现规律,并处理数字0的特殊情况,得出解决方案。时间复杂度为O(log n),空间复杂度为O(n)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目概述

    试计算在区间 1 到 n 的所有整数中,数字 x(0 ≤ x ≤ 9)共出现了多少次?例如,在 1

到 11 中,即在 1、2、3、4、5、6、7、8、9、10、11 中,数字 1 出现了 4 次。

解题思路

    本题直接将每个数的每一位抠出来比较就能过,但我们现在讨论另一种做法。

    对于个位上的数字,每10个数中出现1次;

    对于十位上的数字,每100个数中出现10次;

    以此类推……

    对于x=0的情况要进行特殊处理:

     当10<=n<=99时,0的出现被算多了00,01,02,03,04,05,06,07,08,09这几个数,一共多出了11次;

     当100<=n<=999时,同理,0被多算了111次;

     ……

    将被多算的部分减去即可。

    时间复杂度:O(log n)

    空间复杂度:O(n)

源程序

const
 b:array[1..9]of longint=(1,10,100,1000,10000,100000,1000000,10000000,100000000);
var
 i,n,a,x,t,p:longint;
begin
 readln(n,x);
 t:=n;
 i:=1;
 while t>0 do
  begin
   a:=a+t div 10*b[i];
   t:=t div 10;
   inc(i);
  end;
 t:=n;
 i:=1;
 while t>0 do
  begin
  p:=t mod 10;
  if p>x then a:=a+b[i];
  if (p=x)and(i>=2) then a:=a+n mod b[i]+1;
  if (p=x)and(i=1) then a:=a+1;
  t:=t div 10;
  inc(i);
  end;
 if x=0 then begin
              p:=1;
              t:=n div 10;
              while t>0 do
               begin
                p:=p*10+1;
                t:=t div 10;
               end;
              a:=a-p;
             end;
 write(a);
end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值