-
题目描述:
-
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。
习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
-
输入:
-
输入包括一个整数N(1<=N<=1500)。
-
输出:
-
可能有多组测试数据,对于每组数据,
输出第N个丑数。
-
样例输入:
-
3
-
样例输出:
-
3
总结:每一步添加的数都由前面的数乘以2、3、5决定,而对应的元素的是线性推移的,记录相应的位置就可以快速求解下一个元素,只需注意以下两点:
1.三个探查位置算出的下一个candidate都不会小于当前最大值(不然是错误状态),但是存在3个里面多个算得相同值的情况,这时候就要更新所有的下标;
2.值增加的比感觉的要快很多,之前简单设了一个1000000的上限结果超出了,不过倒没有超出int的范围(第1500个:859963392)
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <map> #include <cmath> #include <assert.h> #include <vector> #include <limits.h> using namespace std; int UglyNum[1510]; void FindUglyNumber(int n) { //记录下一个要添加的数字下标位置 int pos[3];//分别对应2、3、5 int factor[3]; factor[0]=2,factor[1]=3,factor[2]=5; UglyNum[1]=1; int count=1; pos[0]=pos[1]=pos[2]=1; while (count<n) { int nextNum=INT_MAX; int choosed=-1; for(int i=0; i<3; i++) if (UglyNum[pos[i]]*factor[i]<nextNum) { nextNum=UglyNum[pos[i]]*factor[i]; choosed=i; } UglyNum[++count]=nextNum; for (int i=0; i<3; i++) if (UglyNum[pos[i]]*factor[i]<=nextNum)//只可能== pos[i]++; //pos[choosed]++; } } int main() { //freopen("in.txt","r",stdin); int n; FindUglyNumber(1500); while (cin>>n) { cout<<UglyNum[n]<<endl; } return 0; } /************************************************************** Problem: 1214 User: xjbscut Language: C++ Result: Accepted Time:50 ms Memory:1516 kb ****************************************************************/