统计出整数1-N中1出现的次数。

来源:互联网 发布:网络硬盘录像机16价格 编辑:程序博客网 时间:2024/05/16 08:05

题目来源:大众点评软件开发实习生技术测试;

题目:如题,统计出整数1-N中1出现的次数。如N=12,则1一共在1,10,11,12这四个数中出现了五次;

解法思想:

以12102为例,暂且从左至右分别称为第1位,第2位,到第bit(bit为数目的位数)位。则1为第1位,2为第2位,3为第3位,0位第4位。

1在第1位出现的次数:10000-12102,共有2103次,即count=(2102+1);

1在第2位出现的次数:01000-11999,共有2*1000次,即count=(1+1)*1000,其中1000为第二位的权值,即第二位为千位,所以乘以1000;

1在第3位出现的次数:00100-11199、12100-12102次,即count=12*100+2+1,100为第三位处于100位,所以乘100;

1在第4位出现的次数:00010-12019,即count=121*10;

1在第5位出现的次数:00001-12101,即count=(1210+1)*1;

假设第i位设为当前位cur,位于第i位左边的假设称为高位most,位于第i位右边的假设称为低位least,当前位所处十进制位的权值称为tmp。由上面的分析可知,

当cur=1时,count=tmp*most+least+1;

当cur>1时,count=(tmp+1)*most;

当cur<1时,count=tmp*most。

算法分析就是这样了,那么下面我们的问题便是,给定一个正整数N,如何用编程语言来求出这个整数的位数、当前位,高位,低位和当前位所在位的权值。

位数bit=(int)log10N+1;

第i位所在位的权值tmp=10^(n-i);

当前位cur=(N/tmp)%10;

高位most=(N/10)/tmp;

低位least=N/tmp.

这是核心问题,解决了这些核心问题,剩下的就比较好解决了。下面贴出我的代码,可直接运行。

// test11.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include"iostream"using namespace std;unsigned long caculate(unsigned long n){unsigned long count=0;int bit = 0;bit = log10(n)+1;int tmp = 0;int cur=0;int most=0;int least=0;for (int i = 0; i < bit; i++){tmp = (int)pow(10, bit-i-1);cur=(n/tmp)%10;most=(n/10)/tmp;least=n%tmp;if (cur==1){count=count+most*tmp+least+1;}else if (cur>1){count=count+most*tmp+tmp;}else{count=count+most*tmp;}}     return count; }int _tmain(int argc, _TCHAR* argv[]){unsigned long iCount = 0;unsigned long n = 0;cout<<"输入你需要统计的数:";cin>>n;iCount=caculate(n);cout<<"总共有"<<iCount<<endl;return 0;}