从1到n的数中1出现的个数,最简单的思路就是从1到n求每个数字中1的个数,这样就是速度太慢了。
可以寻找规律,假设数为abcde,c在百位上,求百位上的数字的方法:如果c等于0或者大于1,1的个数只与左边有关(即ab),如果c等于1,1的个数和左边右边都有关(即de)。
具体见代码:
#include<iostream>
#include<math.h>
#include<time.h>
using namespace std;
int basecalsum(int number){
int sum =0;
for(int i =1;i<=number;i++){
int temp = i;
while(temp != 0){
if(temp%10 == 1)
++sum;
temp/= 10;
}
}
return sum;
}
int fastcalsum(int number){
int leftnum,rightnum,curnum,sum =0;
int pos =1;
while(number/pos!= 0){
leftnum = number/(pos*10);
rightnum= number-(number/pos)*pos;
curnum = (number/pos)%10;
switch(curnum){
case 0:
sum += leftnum*pos;
break;
case 1:
sum += leftnum*pos+rightnum+1;
break;
default:
sum += (leftnum+1)*pos;
break;
}
pos *=10;
}
return sum;
}
int main(){
clock_t start,end;
double duration;
int sum1,sum2;
start = clock();
sum1 = basecalsum(100000000);
end = clock();
printf("基本方法输出为%d,损耗时间为%f秒\n",sum1,(double)(end-start)/CLOCKS_PER_SEC);
start = clock();
sum1 = fastcalsum(100000000);
end = clock();
printf("快速的方法输出为%d,损耗时间为%f秒\n",sum1,(double)(end-start)/CLOCKS_PER_SEC);
system("PAUSE");
return 0;
}
丑数指的是因子中只有2,3,5的数,比如求第1500个丑数也可以一个一个的算,直到1500.如果数字很大还是太慢。
所以我们考虑用空间换时间,即1为最小的丑数,那么其它丑数都可以分解成更小的丑数乘积。所以用数组存储之前的丑数,然后进行计算。为了简化计算可以不用数组中的每个数都来判断,可以每算出一个进行对比,如果是小于则跳过。说的不太清楚,具体看代码。
#include<iostream>
#include<math.h>
#include<time.h>
using namespace std;
//基本方法
bool isurgly(int a){
while(a%2 == 0)
a/=2;
while(a%3 == 0)
a/=3;
while(a%5 == 0)
a/=5;
return (a==1) ? true : false;
}
int basefindurgly(int number){
int count = 0;
int num = 0;
while(count<number){
++num;
if(isurgly(num))
++count;
}
return num;
}
//快速方法
int fastfindurgly(int number){
//int *urgnum = (int *)malloc(sizeof(number+1));
int *urgnum = new int[number];
int pos2,pos3,pos5;
pos2 = pos3 = pos5 =0;
urgnum[0] = 1;
int i =1;
while(i < number){
int temp = urgnum[pos2]*2;
if(temp >urgnum[pos3]*3)
temp = urgnum[pos3]*3;
if(temp >urgnum[pos5]*5)
temp = urgnum[pos5]*5;
urgnum[i] = temp;
if(urgnum[pos2]*2 <= urgnum[i])
++pos2;
if(urgnum[pos3]*3 <= urgnum[i])
++pos3;
if(urgnum[pos5]*5 <= urgnum[i])
++pos5;
++i;
}
int result = urgnum[number-1];
delete [] urgnum;
return result;
}
int main(){
int result;
clock_t start,end;
start = clock();
result = basefindurgly(1500);
end = clock();
printf("结果为%d,时间为%f seconds\n",result,(double)(end-start)/CLOCKS_PER_SEC);
start = clock();
result = fastfindurgly(1500);
end = clock();
printf("结果为%d,时间为%f seconds\n",result,(double)(end-start)/CLOCKS_PER_SEC);
system("PAUSE");
return 0;
}