[正经题解]按位数学统计
2026-08-26 17:10:34
发布于:河南
2阅读
0回复
0点赞
核心思想
个位、十位、百位…… 每一位分开算:单独算「在这一位上 2 一共出现多少次」,全部累加。
把数字拆成三部分:
base:当前位的基数,个位base=1,十位base=10,百位base=100high:当前位左边高位cur:当前位本身的数字low:当前位右边低位
三种分支规则(针对统计数字 2)
- cur < 2:当前位数字比 2 小
这一位出现 2 的次数:
high * base
- cur == 2:当前位正好等于 2
这一位出现 2 的次数:
high * base + low + 1
- cur > 2:当前位数字比 2 大
这一位出现 2 的次数:
(high + 1) * base
不断base *=10,从个位一直处理到最高位,把每一位的结果累加就是答案。
#include<cstdio>
int count_num(int t,int num);
signed main(void){
int l,r;
scanf("%d%d",&l,&r);
printf("%d",count_num(r,2)-count_num(l-1,2));
return 0;
}
int count_num(int t,int num){
int cnt=0;
int base=1;
while(base<=t){
int high=t/(base*10);
int cur=(t/base)%10;
int low=t%base;
if(cur<num) cnt+=high*base;
else if(cur==num) cnt+=high*base+low+1;
else cnt+=(high+1)*base;
base*=10;
}
return cnt;
}
通俗理解每一种情况
举例子,统计十位上 2 出现多少次:
- cur<2:比如 517,十位是 1。十位上 2 只能来自 0~4 循环,每轮 10 次,
high*base。 - cur=2:比如 527。完整轮次
high*base,再加上 0~low(0‑7)一共 low+1 个。 - cur>2:比如 537。可以取到 0‑5 全部轮次,所以
(high+1)*base。
注意点:
1.要用long long,防止溢出!t 很大时 int 会爆。本题不用
2.base 会不断 ×10,循环条件base <= t。
3.num的取值范围是{1,2,3,4,5,6,7,8,9}num=0时代码有改动不能用,嘻嘻
最后再说一下本方法的复杂度:O(log n)
点个赞吧


这里空空如也




有帮助,赞一个