由于思维的惯性,用了queue。后来发现一要注意要用集合判重,二是每次往queue里放的多,后来溢出了,要用long long。但这样要用数组,集合,队列,内存多。效率是O(n*logn)的。
#include <iostream> #include <algorithm> #include <memory.h> #include <vector> #include <queue> #include <set> #include <functional> #define LEN 1505 #define ulong unsigned long long using namespace std; ulong dp[LEN]; int main() { priority_queue<ulong, vector<ulong>, greater<ulong> > que; set<ulong> visit; que.push(1); visit.insert(1); int i = 0; while (i < LEN) { i++; int node = que.top(); que.pop(); dp[i] = node; if (visit.count(node*2) == 0) { que.push(node*2); visit.insert(node*2); } if (visit.count(node*3) == 0) { que.push(node*3); visit.insert(node*3); } if (visit.count(node*5) == 0) { que.push(node*5); visit.insert(node*5); } } int n; while (cin >> n) { cout << dp[n] << endl; } }
另有效率O(n),空间O(1)的方法。因为本质上是已有的丑数*2,*3,*5的结果在竞争,那么每次记录*2,*3,*5的丑数的编号(用数组记录已经生成的丑数),然后比较产生最小的,就是下一个丑数。
http://blog.csdn.net/acm_zl/article/details/10613073
#include <iostream> #include <memory.h> #define MIN(a,b) a<b?a:b #define LEN 1505 #define ulong unsigned long long using namespace std; ulong ugly[LEN]; int main() { memset(ugly, 0, sizeof(ugly)); ugly[1] = 1; int index2 = 1; int index3 = 1; int index5 = 1; for (int i = 2; i < LEN; i++) { ulong m2 = 2 * ugly[index2]; ulong m3 = 3 * ugly[index3]; ulong m5 = 5 * ugly[index5]; int tmp = MIN(m2, m3); ulong m = MIN(tmp, m5); ugly[i] = m; if (m == m2) index2++; if (m == m3) index3++; if (m == m5) index5++; } int n; while (cin >> n) { cout << ugly[n] << endl; } }