/**********************************************************************************
*数字分布问题
*计算[0,N]范围内,特定数字的个数。譬如计算[0,12]范围内1 的个数,即:f(12)= 5
*算法1(暴力循环):从1-N,累加每一个数字中的1的个数 O(N*logN)
*算法2(寻找规律,得到公式):任一位置上1的个数都由:当前位(cur),高位(high),低位(low)3个位置决定
* count+=high*i; //与高位的关系,每次都直接叠加
* 1.cur<1 count+=0; //与当前位置的关系
* 2.cur=1 count+=low+1; //当前位是1的时候,跟低位也有关系
* 3.cur>1 count+=i;
*推广 计算[0,N]范围内的0-9的分布,#define DIGIT 1(修改DIGIT的值即可)
*anthor: fangchang
*time: 2016/04/04 12:14
************************************************************************************/
#include<stdio.h>
#define DIGIT 2
int numOfSpecialDigit(int i);
void answer(); //暴力法
void answer2(); //公式法
int main() {
int x=1;
while(x!=0) {
printf("input x(x=0:game over):\n");
scanf("%d",&x);
printf("this is answer():\n");
answer();
printf("this is answer2():\n");
answer2();
}
fflush(stdin);
getchar();
return 0;
}
void answer() {
int i ;
int n;
int count=0;
printf("please input a digit for n(n>=0):\n");
scanf("%d",&n);
for(i=0;i<=n;++i) {
count+=numOfSpecialDigit(i);
}
printf("[0,%d] has %d %d\n",n,count,DIGIT);
}
int numOfSpecialDigit(int i){ //每一个数字中的特定数字个数
int count=0;
int tmp;
while(i) {
tmp=i%10;
count += tmp==DIGIT ? 1:0;
i=i/10;
}
return count;
}
void answer2() {
int cur_digit;
int high_digit;
int low_digit;
int n;
int i=1; //从个位开始
int count=0;
printf("please input a digit for n(n>=0):\n");
scanf("%d",&n);
while(0!=(n/i)) {
cur_digit = (n/i)%10; //得到当前位
high_digit = n/(i*10); //得到高位
low_digit = n - (n/i)*i; //得到低位
count+=high_digit*i;
if(cur_digit<DIGIT) { //小于,则该位没有特定数字
count += 0;
}
else if(cur_digit == DIGIT) { //等于时,个数由低位决定
count+=low_digit+1;
}
else if(cur_digit>DIGIT) { //大于,则直接加该位的权值即可(百位就加100)
count += i;
}
i*=10; //权值。个位结束,则计算十位,依次进行
}
printf("[0,%d] has %d %d\n",n,count,DIGIT);
}
end.
[0,N]范围内0到9的分布统计
最新推荐文章于 2021-03-31 10:05:00 发布