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次方了
AC代码:
题目传送门: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; }
相关文章推荐
- HDU 5878 -- 丑数打表(2016 ACM/ICPC Asia Regional Qingdao Online)
- HDU 5878 I Count Two Three (暴力) 2016 ACM/ICPC Asia Regional Qingdao Online
- HDU 5878 I Count Two Three (2016 ACM/ICPC Asia Regional Qingdao Online 1001)
- hdu--5878(hdu 5878 I Count Two Three (2016 ACM/ICPC Asia Regional Qingdao Online 1001))
- hdu 5878 I Count Two Three (2016 ACM/ICPC Asia Regional Qingdao Online 1001)
- HDU 5883 The Best Path(并查集+欧拉回路 or 欧拉路)——2016 ACM/ICPC Asia Regional Qingdao Online
- HDU 5889 Barricade (最小割) 2016 ACM/ICPC Asia Regional Qingdao Online
- HDU 5883 The Best Path 2016 ACM/ICPC Asia Regional Qingdao Online
- HDU 5884 Sort 2016 ACM/ICPC Asia Regional Qingdao Online 1007
- HDU 5878 I Count Two Three 2016 ACM/ICPC Asia Regional Qingdao Online 1001
- HDU 5889 Barricade 【BFS+最小割 网络流】(2016 ACM/ICPC Asia Regional Qingdao Online)
- HDU 5883 The Best Path (欧拉通路) 2016 ACM/ICPC Asia Regional Qingdao Online
- HDU 5881 Tea (水题) 2016 ACM/ICPC Asia Regional Qingdao Online
- HDU 5879 Cure 2016 ACM/ICPC Asia Regional Qingdao Online
- HDU 5881 Tea(思维)——2016 ACM/ICPC Asia Regional Qingdao Online
- HDU 5879 Cure 2016 ACM/ICPC Asia Regional Qingdao Online 1002
- 2016 ACM/ICPC Asia Regional Qingdao Online hdu 5884 Sort (二分+优先队列)★
- 2016 ACM/ICPC Asia Regional Qingdao Online hdu 5889 Barricade (最短路+最小割)
- HDU 5879 Cure(技巧)——2016 ACM/ICPC Asia Regional Qingdao Online
- 2016 ACM/ICPC Asia Regional Qingdao Online 1001 I Count Two Three(打表+二分搜索)