丑数 打表+二分查找

1010 只包含因子2 3 5 的数

题目链接:

http://www.51nod.com/Challenge/Problem.html#!#problemId=1010

引用知识:

https://baike.baidu.com/item/%E4%B8%91%E6%95%B0/18046116?fr=aladdin

丑数

丑数描述

编辑

把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但7、14不是,因为它们包含质因子7。 习惯上我们把1当做是第一个丑数。

前20个丑数为:1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36。

判断方法

编辑

首先除2,直到不能整除为止,然后除5到不能整除为止,然后除3直到不能整除为止。最终判断剩余的数字是否为1,如果是1则为丑数,否则不是丑数。

 

 

K的因子中只包含2 3 5。满足条件的前10个数是:2,3,4,5,6,8,9,10,12,15。

所有这样的K组成了一个序列S,现在给出一个数n,求S中 >= 给定数的最小的数。

例如:n = 13,S中 >= 13的最小的数是15,所以输出15。

输入

第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000)
第2 - T + 1行:每行1个数N(1 <= N <= 10^18)

输出

共T行,每行1个数,输出>= n的最小的只包含因子2 3 5的数。

输入样例

5
1
8
13
35
77

输出样例

2
8
15
36
80

解题思路:丑数打表+二分查找。如果去枚举的话,抱歉time limittted!!!

 

下面是我的代码

#include "bits/stdc++.h"
using namespace std;
#define LL long long
LL a[100000];
LL ugly(LL n)
{
  while(n>=2&&n%2==0){
    n/=2;
  }
  while(n>=5&&n%5==0){
    n/=5;
  }
  while(n>=3&&n%3==0){
    n/=3;
  }
  if(n==1) return 1;
  else return 0;
}
LL min1(LL a,LL b,LL c)
{
  LL c1=min(a,b);
  LL d=min(c1,c);
  return d;
}
int bsearch(LL a[], int n,LL key){
    int low = 0;
    int high = n;
    int mid = 0;
    while(low <= high) {
        mid = low + ((high-low) >> 1);
        if(key <= a[mid]) {
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    return low <= n ? low : -1;
}
int main(int argc, char const *argv[]) {
  int t;
  int n=1;
  cin>>t;
  a[1]=1;
  int p2,p3,p4;
   p2=p3=p4=1;
  while(n<11000)
  {
    a[++n]=min1(2*a[p2],3*a[p3],5*a[p4]);
    if(a[n]==2*a[p2]) p2++;
    if(a[n]==3*a[p3]) p3++;
    if(a[n]==5*a[p4]) p4++;
  }
  // cout<<a[11000]<<endl;
  // for(int i=1;i<10;i++)
  // cout<<a[i]<<" "<<endl;
  for(int i=0;i<t;i++)
  {
    LL n2;
    cin>>n2;
    // cout<<n2<<endl;
    if(n2==1) printf("2\n");
    else{
    int x=bsearch(a,n,n2);
    // cout<<x<<endl;
    cout<<a[x]<<endl;
  }
  }
  return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值