紫书—关于例题5-7丑数的思考

  题目链接:https://vjudge.net/problem/UVA-136

  主要思路:1.正常思路:用一个for循环挨个判断i值是否是丑数并记录,当到达1500个丑数时就输出该数字.此思路容易想到,但难以实现.我们可以反过来思考.

                 2.优化思路:已知1是丑数,我们将1放入一个优先队列中,每次取出一个优先队列中最小的数并记录,将最小数依次乘上2,3,5,并判断是否重复,若不重复则放入set和priority_queue中,当到达1500个数字时输出                   并跳出循环.

  AC代码:

#include<bits/stdc++.h>
using namespace std;
int dis[3]={2,3,5};
typedef long long ll;//开int会溢出
int main(){
    priority_queue<ll,vector<ll>,greater<ll> >que;   //最小堆的建立方式
    set<ll>m;
    que.push(1);
    for(int i=1;;i++){
        ll k=que.top();
        que.pop();
        if(i==1500){
            cout<<"The 1500'th ugly number is "<<k<<'.'<<endl;
            break;
        }
        for(int j=0;j<3;j++){
            ll h=k*dis[j];
            if(!m.count(h)){//判断是否重复
                que.push(h);
                m.insert(h);
            }
        }
    }
}

  注意事项:1.要开long long,不然int类型会溢出.  

                 2.最小堆的建立方式于最大堆的不同.

posted @ 2021-05-10 13:28  江间暮云  阅读(68)  评论(0)    收藏  举报