http://oj.ecustacm.cn/problem.php?id=1362
题目描述
到x星球旅行的游客都被发给一个整数,作为游客编号。
x星的国王有个怪癖,他只喜欢数字3,5和7。
国王规定,游客的编号如果只含有因子:3,5,7,就可以获得一份奖品。
前10个幸运数字是:3 5 7 9 15 21 25 27 35 45,因而第11个幸运数字是:49
小明领到了一个幸运数字 59084709587505。
去领奖的时候,人家要求他准确说出这是第几个幸运数字,否则领不到奖品。
请你帮小明计算一下,59084709587505是第几个幸运数字。
输出
输出一个整数表示答案
https://blog.csdn.net/weixin_43914593/article/details/112637248
1.暴力
c++
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<set>
#include<queue>
#include<stack>
#include<map>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn = 101000;
#define inf 2147483678
int main()
{
long long n=59084709587505;
int cnt=0;
for(int i=0;pow(3,i)<n;i++)
{
for(int j=0;pow(5,j)<n;j++)
{
for(int k=0;pow(7,k)<n;k++)
{
if(pow(3,i)*pow(5,j)*pow(7,k)<n)
cnt++;
}
}
}
cout<<cnt;
return 0;
}
python
python不怕大数并且运行起来比c++快多了
cnt=0;
for i in range(50):
for j in range(50):
for k in range(50):
r1=3**i
r2=5**j
r3=7**k
if r1*r2*r3<59084709587505:
cnt+=1;
print(cnt)
java
package test;
public class test1 {
public static void main(String[] args)
{
int cnt=0;
long n=59084709587505L;
for(int i=0;Math.pow(3,i)<n;i++)
for(int j=0;Math.pow(5,j)<n;j++)
{
for(int k=0;Math.pow(7,k)<n;k++)
{
if(Math.pow(3,i)*Math.pow(5,j)*Math.pow(7,k)<n)
cnt++;
}
}
System.out.println(cnt);
}
}
2.硬算+排序
python
硬算的核心是进行排序,找出最小的来与3,5,7相乘
n = 59084709587505
a = [1]
k = 0
while True:
for i in range(3,8,2):
tmp=i*a[k]
if tmp not in a:
a.append(tmp)#将tmp插入a
a.sort()
if tmp > 2**64:
print(a.index(n))#找出n在a中的index
exit(0)#return 0
k+=1
3.priority_queue+set/map(去重)
python
#range 用法
range(start,end,step)
#python中queue和set的使用
import queue
q=queue.PriorityQueue()
s=set()
q.put(1)
s.add(1)
cnt=0
while True:
n=q.get()
if n== 59084709587505:
break
cnt+=1
for i in range(3,8,2):#range(start,end,step)
t=n*i
if t not in s:
q.put(t)
s.add(t)
print(cnt)
c++
ans的计数是以循环的数量==从优先队列中取出的最小值的数量为基准的
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<set>
#include<queue>
#include<stack>
#include<map>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn = 101000;
#define inf 2147483678
priority_queue<ll,vector<ll>,greater<ll>>pq;
map<ll,int>mp;
int sum[5]={3,5,7};
int main()
{
ll n=59084709587505;
pq.push(1);
int ans=0;
while(1)
{
ll cnt=pq.top();
pq.pop();
if(cnt==n)
{
cout<<ans<<endl;
break;
}
ll tmp;
for(int i=0;i<3;i++)
{
tmp=cnt*sum[i];
if(mp[tmp]==0)
{
pq.push(tmp);
mp[tmp]=1;
}
}
ans++;
}
}
4.set+upper_bound
https://blog.csdn.net/qq_40160605/article/details/80150252
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
利用upper_bound寻找set里最小的那个数字(比当前的数字大)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<set>
#include<queue>
#include<stack>
#include<map>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn = 101000;
#define inf 2147483678
set<ll>s;
int sum[5]={3,5,7};
int main()
{
ll f=1;
while(1)
{
for(int i=0;i<3;i++)
{
if(f*sum[i]<=59084709587505)
s.insert(f*sum[i]);
}
f=*s.upper_bound(f);
if(f>=59084709587505)
break;
}
cout<<s.size();
return 0;
}