您的位置:首页 > 理论基础 > 计算机网络

HDU 5878 -- 丑数打表(2016 ACM/ICPC Asia Regional Qingdao Online)

2016-09-17 21:27 363 查看
[align=left][/align]
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5878

题意:输入一个n,要求找出比n大的,因子只有2,3,5,7的最小的数。

题解:首先说一下什么是丑数,因子只有2,3,5,7的数就是丑数。。。。然后,该怎么做呢?肯定不能从n开始,一个一个暴力找,从题目的样例来看,当n是10的9次方时,要找两万多遍,会超时。如果做过丑数相关的题的话,就会知道其实10的9次方个数里面,丑数其实不多,可以直接打表,然后通过二分法把离n最近的丑数找出来。怎么打表就是关键了。

首先,第一个丑数为“1”,后面的每一个丑数都是有前一个丑数乘2、3、5或7而来,那么后一个丑数就是前一个乘这四个数得到的最小值,for example:第一个:1,第二个:1*2、1*3、1*5或1*7,显然为2,第三个:2*2,1*3,1*5或1*7,显然是3,第四个:2*2,,2*3,1*5,1*7为4,第五个:3*2,2*3,1*5,1*7…… 

以下代码枚举了5842个丑数,从小到大存在a数组里面,输出一下第5842个丑数,发现已经是2*10的9次方了

#include <iostream>
#include <cstdio>
#define min(a,b) ((a)<(b)?(a):(b))
#define min4(a,b,c,d) min(min(a,b),min(c,d))
using namespace std;
int a[5850];

int main()
{
int n=1;
int p2,p3,p5,p7;
p2=p3=p5=p7=1;
a[1]=1;
while(n<5843){
a[++n]=min4(2*a[p2],3*a[p3],5*a[p5],7*a[p7]);
if(a
==2*a[p2])p2++;
if(a
==3*a[p3])p3++;
if(a
==5*a[p5])p5++;
if(a
==7*a[p7])p7++;
}
return 0;
}




AC代码:

#include <iostream>  
#include <cstdio>  
#define min(a,b) ((a)<(b)?(a):(b))  
#define min4(a,b,c,d) min(min(a,b),min(c,d))  
using namespace std;  
int a[5850];  

int bSearch(int begin, int end, int e)
{
    int mid, left = begin, right = end;
    while(left <= right){
        mid = (left + right) >> 1;
        if(a[mid] >= e) right = mid - 1;
        else left = mid + 1;
    }
    return left;
}

int main()  
{  
    freopen("input.txt","r",stdin);  
    int n=1, T;
    int p2,p3,p5,p7;  
    p2=p3=p5=p7=1;  
    a[1]=1;  
    while(n<5843){  
        a[++n]=min4(2*a[p2],3*a[p3],5*a[p5],7*a[p7]);
        if(a
==2*a[p2])p2++;
        if(a
==3*a[p3])p3++;  
        if(a
==5*a[p5])p5++;  
        if(a
==7*a[p7])p7++; 
    }  
    cin>>T;
    while(T--){
          scanf("%d",&n);
          printf("%d\n",a[bSearch(1,5842,n)]);
    }
    return 0;  
}  



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐