2016青岛online——I count two three

本文介绍了一种算法思路,用于求解大于给定整数n的最小数,该数可以表示为2^a*3^b*5^c*7^d的形式。通过预先计算所有可能的组合并使用二分查找来快速定位目标值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门

题意:输入n,求出能分解为2^a*3^b*5^c*7^d的大于n的最小数

基本思路:打表写出所有能分解为2^a*3^b*5^c*7^d的数,然后二分查找,lower_bound

复杂度:32*21*13*11

一开始不会的原因:想到要打表,但是不知道怎么入手,有多少个数,做题少

解决:2:0~31;3:0~20;5:0~12;7:0~10.最多32*21*13*11个,实际上远少于这个

坑点:一定要注意会不会爆。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int MAXN=1e9+1e5;//+1e5是为了保证打出的表包括n为1e9时
int ans[103500];//32*21*13*11
int main()
{
	ll p;
	int tot=0;
	//打表,预处理 
	for(int i=0;i<=31;i++)
	{
		for(int k=0;k<=20;k++)
		{
			for(int m=0;m<=13;m++)
			{
				for(int n=0;n<=10;n++)
				{
					p=pow(2,i)*pow(3,k);
					if(p>=MAXN)
					{
						continue;
					}
					else
					{
						p*=pow(5,m);
						if(p>=MAXN)
						{
							continue;
						 } 
						 else
						{
							p*=pow(7,n);
							if(p>=MAXN)
							{
								continue;
							}
							else
							{
								ans[tot++]=(int)p;
							}
						}
					}
				}
			}
		}
	}
//	printf("%d\n",tot);
//	sort(ans,ans+tot);
//	for(int i=0;i<100;i++)
//	{
//		printf("%d\n",ans[i]);
//	}
//排序,以便二分
    sort(ans,ans+tot);
    int t;
    scanf("%d",&t);
    int n;
    while(t--)
    {
		scanf("%d",&n);
//前闭后开,返回大于等于n的第一个位置
		int index=lower_bound(ans,ans+tot,n)-ans;
		printf("%d\n",ans[index]);    	
	}
 } 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值