问题描述
输入正整数n,判断从1到n之中,数字1一共要出现几次。例如1123这个数,则出现了两次1。例如15,那么从1到15之中,一共出现了8个1。
输入格式
一个正整数n
输出格式
一个整数,表示1出现的资料
样例输入
15
样例输出
8
数据规模和约定
n不超过30000
#include<iostream>
#include<math.h>
using namespace std;
int main(){
string n;
int a[5];
a[0]=1;
for(int i=1;i<5;i++){
a[i]=10*a[i-1]+pow(10,i);
}
//求出9,99,999,9999中含1的个数。
/*for(int i=0;i<5;i++){
cout<<a[i]<<endl;
}*/
while(cin>>n){
int cnt=0;
for(int i=0;i<n.length();i++){
int num=n[i]-'0';//num表示当前位上的数值
if(i==n.length()-1){
if(num>=1)cnt++;
}else{
int num=n[i]-'0';
if(num>1){
cnt+=(num)*a[n.length()-2-i]+pow(10,n.length()-1-i);
}
else if(num==1){
int cun=0;
for(int j=i+1;j<n.length();j++){
cun*=10;
cun+=n[j]-'0';
}
cnt+=a[n.length()-2-i]+cun+1;
}
}
}
cout<<cnt<<endl;
}
return 0;
}
处理方法:随便举一个例子:先定义函数f(x)表示x中含有1的个数,则5394这个数中1的个数为:
*f(5294)=(5+1)f(999)+294+1
在一开始的步骤中就已经算出,9,99,999等数中1的个数。剩下的就是对特殊情况的讨论。
当然这种情况直接用循环从1到n进行循环,算出每个数中含1的个数,再直接累加求和,那么结果显然是超时的,随着数字增大时间复杂度比数字增长的倍数还大。
用公式的话是明显比暴力来得好啦啦啦。