題目描述:UVA136
思路:對(duì)于每個(gè)丑數(shù)x,2x,3x,5*x也是丑數(shù),所以利用優(yōu)先隊(duì)列,每次取出最小的一個(gè)數(shù)然后再利用set容器判斷這個(gè)數(shù)的2倍,3倍,5倍數(shù)是否出現(xiàn),否就添加入優(yōu)先隊(duì)列和set容器。(注意:數(shù)據(jù)要設(shè)為long long,int會(huì)產(chǎn)生數(shù)據(jù)溢出)
#include <iostream>
#include <cstdio>
#include <queue>
#include <set>
#include <vector>
#include <iterator>
using namespace std;
typedef long long LL;
LL op[3] = {2,3,5};
int main()
{
priority_queue< LL,vector<LL>,greater<LL> >pq;//小的數(shù)字優(yōu)先出列,可以理解為急診的病人允許插隊(duì)
set<LL>s;
pq.push(1);
s.insert(1);
for(int cnt = 1;;cnt++){
LL x = pq.top();pq.pop();
if(cnt==1500){
printf("The 1500'th ugly number is %lld.\n",x);
break;
}
for(int i = 0;i<3;i++){
LL x2 = x*op[i];
if(s.count(x2)==0){
s.insert(x2);
pq.push(x2);
}
}
}
return 0;
}
思考:這道題主要練習(xí)如何去使用STL里面的優(yōu)先隊(duì)列,這里用的越小數(shù)字優(yōu)先出列可以應(yīng)用到以后的數(shù)字打表中,例如素?cái)?shù)打表,幸運(yùn)數(shù)打表,因?yàn)閟et容器存儲(chǔ)利用的是平衡二叉樹(shù)(RB樹(shù))的結(jié)構(gòu)所以可以利用來(lái)快速判重,再加數(shù)字優(yōu)先隊(duì)列就可以完成打表工作。(適合以后的規(guī)律題)
附上set的基本操作:
set集合是c++ stl庫(kù)中自帶的一個(gè)容器,set具有以下兩個(gè)特點(diǎn):
1、set中的元素都是排好序的
2、set集合中沒(méi)有重復(fù)的元素
常用操作:
begin() 返回set容器的第一個(gè)元素的地址
end() 返回set容器的最后一個(gè)元素地址
clear() 刪除set容器中的所有的元素
empty() 判斷set容器是否為空
max_size() 返回set容器可能包含的元素最大個(gè)數(shù)
size() 返回當(dāng)前set容器中的元素個(gè)數(shù)
erase(it) 刪除迭代器指針it處元素
insert(a) 插入某個(gè)元素