蓝桥杯每日一题1.16 2018省赛A组4.第几个幸运数[priority_queue+set][set+upper_bound]

14 篇文章 0 订阅
3 篇文章 0 订阅

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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值