1的数目


题目描述:给定一个正整数N,写出从1到N所有整数,然后数一下其中出现的所有1的个数。

例如:

N=2, 写下1, 2 这样只出现一个1

N=12,写下1 ,2 ,3, 4, 5, 6, 7, 8, 9, 10, 11, 12.这样出现1的个数是5.

问题是写出一个函数f(N)表达1出现的个数,其中n 的大小为32位。


解答:

1. 最简单也是最蛮力的做法就是枚举,把每个数都找出其中出现1的个数

while(n!=0){

num+= (n%10==1)? 1:0;

n /= 10;

}

这种暴力的方法只适合于数据比较小的时候。时间的复杂度为Nlog2(N),

2.我们来仔细的归纳对于给定的N,似乎可以分析每一位上可能出现1的次数,之和来得到结果。假设N=13

十位出现1的个数 4

个位出现1的个数 2

       F(N)= 4+2 = 6;

假设N=abcde, a,b,c,d,e分别表示十进制各个位数上的数字。如果要计算百位出现1的次数,它将会受到三个因素的影响。当百位,百位以下,百位以上。

如果百位为0, 则由高位决定,比如12013, 可知道百位出现1的个数100-199, 1100-1199, 2100-2199,。。。。11100-11199.一共是1200个。也就是高位数字12决定,12*100。

如果百位为1,则由高位12*100决定,并且有12100-12113,一共114个,等于地位113+1.

如果百位大于1,则由更高位决定,比如12213百位出现1 的可能个数100-199, 1100-1199, 2100-2199.。。。。。 12100-12199一共是1300个,并且等于更高位数字(12+1)*100

所以归纳出的代码是:

#include<iostream>
using namespace std;

int main() {
	long long n;
	cin>>n;
	long long factor = 1;
	long long low = 0;
	long long curr = 0;
	long long high = 0;
	long long count = 0;
	while(n/factor != 0) {
		low = n - n/factor*factor;
		curr = (n/factor)%10;
		high = n/(factor*10);
		switch(curr){
			case 0:
				count += high*factor;
				break;
			case 1:
				count += high*factor + low + 1;
				break;
			default:
				count += (high+1)*factor;
				break;	
		}
		factor *= 10;
	}
	cout<<count<<endl;
	system("pause");
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值