[jobdu]丑数

由于思维的惯性,用了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;
    }
}

  

 

转载于:https://www.cnblogs.com/lautsie/p/3400526.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值