题解 P1179 【数字统计】

Sweetlemon

2017-02-11 14:55:27

Solution

这也许是水题,但是我做复杂了…… 我的方法有O(lg r)的时空复杂度哦~ 思路是:ans=f(r)-f(l-1),其中f(x)表示[1,x]的整数中所含数字2的个数。 f(x)的求法是:逐位求数字2的个数。从右到左第i位(0≤i≤$\lg x$)数字2的个数为$\frac{x}{10^{i+1}}\times 10^{i}+e_{i}$。(注意!要先除再乘!) 其中$e_{i}$的求法为: 1.若$x \mod 10^{i+1}\geq 3\time 10\times 10^{i}$,则$e_{i}=10^{i} $ 2.若$2\time 10\times 10^{i} \leq x \mod 10^{i+1}< 3\time 10\times 10^{i}$,则$e_{i}=x \mod 10^{i+1}-2\time 10\times 10^{i}+1 $。 ---------------------------------------------------- 这里对10的自然数次幂打了表,防止重复计算。 下面是代码: ```cpp #include <stdio.h> //#include <math.h> //此处说明,使用C提交时,竟不能使用数学函数!所以便不用log,而强制把计算的i的上界改为6 int twos(int n); //twos(n)即f(x) int tpow[]={1,10,100,1000,10000,100000,1000000,10000000}; //打表10的幂 int main(void){ int l,r; scanf("%d%d",&l,&r); printf("%d",twos(r)-twos(l-1)); return 0; } int twos(int n){ int count=0,i; //int bits=log(n)/log(10)+1; //数学函数无法使用,故用下一行代之 const int bits=7; for (i=0;i<bits;i++){ count+=n/tpow[i+1]*tpow[i]; if (n%tpow[i+1]>=3*tpow[i]) count+=tpow[i]; else if (n%tpow[i+1]>=2*tpow[i]) count+=(n%tpow[i+1]-2*tpow[i]+1); } return count; } ```