紫薯 例题5-7
一、题意
输出从小到大排列的第1500个丑数。
丑数定义:不能被2,3,5以外的其它素数整除的数。
二、解析
不能被其它素数整除,也就是说丑数质因子分解后只有2,3,5,所以丑数就是有这三个数的乘积组成的。用一个优先队列维护已经求出的最小丑数。从1开始,每次从优先队列中取出当前最小的丑数,然后将它的2,3,5倍放入队列中,来扩充丑数序列,注意队列中已经存在的数就不要重复放了,因此还需要用一个set来记录队列中是否已经存在某个数了。
三、代码
#include <iostream> #include <queue> #include <vector> #include <set> using namespace std; using LL = long long; const int k[3] = {2, 3, 5}; priority_queue<LL, vector<LL>, greater<LL> > q; set<LL> ans; int n = 1500; LL x; int main() { q.push(1); ans.insert(1); while(n --) { x = q.top(); q.pop(); for(int i = 0; i < 3; i ++) { LL m = x * k[i]; if(!ans.count(m)) q.push(m), ans.insert(m); } } cout << "The 1500'th ugly number is " << x << "." << endl; }
归纳
- 优先队列priority_queue、集合set的应用
- 做题时要注意数字范围,有时要用LL
想当年这道题卡了好久...应该是做的第3次了,终于有点进步的感觉了2333