题目描述
李老师的lucky number 是3,5和7,他爱屋及乌,还把所有质因数只有3,5,7的数字认定为lucky number,比如9, 15, 21, 25等等。请聪明的你帮忙算一算小于等于x的lucky number有多少个?
输入数据
一个正整数x,3=<x<=1000000000000
输出数据
小于等于x的lucky number的个数。
样例输入
49
样例输出
11
分析
分析题意,幸运数字是指
的数字,如:
幸运数字9:a=2,b=0,c=0
幸运数字15:a=1,b=1,c=0
幸运数字21:a=1,b=0,c=1
幸运数字25:a=0,b=2,c=0
则寻找小于等于x的幸运数字,就转换成了寻找满足
条件的所有a,b,c的可能组合
题解
算法可分一下步骤进行:
- 分别计算数字x中包含的因数3的个数,5的个数以及7的个数,并分别记为a,b,c
- 遍历所有的a,b,c,排除掉所有
的数字,则剩下的就是满足
条件的数字个数
代码
#include<iostream>
using namespace std;
#define ll long long
//快速幂,计算a的b次方
ll ksm(ll a,ll b)
{
ll base=a,res=1;
while(b)
{
if(b&1) res*=base;
b>>=1;
base*=base;
}
return res;
}
//计算数字n里有几个base因数
int get_cnt(ll n,int base)
{
int cnt=0;
while(n>=base)
{
cnt+=1;
n/=base;
}
return cnt;
}
void sol(ll n)
{
int a=get_cnt(n,3);//计算数字n包含几个3
int b=get_cnt(n,5);//计算数字n包含几个5
int c=get_cnt(n,7);//计算数字n包含几个7
ll ans=-1;
for(int i=0;i<=a;i++)
{
for(int j=0;j<=b;j++)
{
if(ksm(3,i)*ksm(5,j)>n) break;
for(int k=0;k<=c;k++)
{
if(ksm(3,i)*ksm(5,j)*ksm(7,k)>n) break;//排除掉不满足条件的数字
ans+=1;
}
}
}
cout<<ans<<endl;
}
int main()
{
ll n=0;
while(cin>>n)
sol(n);
return 0;
}