UVA 136 & POJ1338 Ugly Numbers

本文介绍了一种使用优先队列和映射数据结构求解丑数的算法,通过实例展示了如何找到第1500个丑数,并提供两种代码实现方案,一种适用于多次询问的场景,另一种用于直接输出特定位置的丑数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:

Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence 
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, … 
shows the first 10 ugly numbers. By convention, 1 is included. 
把只含有2.3.5因数的数称为丑数,默认第一个丑数是1。 
POJ是有多次询问,输出第n个丑数 
UVA是询问第1500个丑数是多少。

思路:

利用STL的优先队列,创建一个小数优先的优先队列,然后每次取队头,分别乘以2.3.5,利用map看是否被放入过队列。从而得到按照大小顺序排列的丑数。

代码:

UVA

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 int main()
 5 {
 6     ll num=1;
 7     priority_queue<ll,vector<ll>,greater<ll> > q;//小数优先的优先队列
 8     map<ll,ll> mp;
 9     int x[3]={2,3,5},cnt=1;
10     q.push(num);
11     mp[num]++;
12     while(!q.empty())
13     {
14         num=q.top();
15         q.pop();
16         if(cnt==1500){
17             cout<<"The 1500'th ugly number is "<<num<<"."<<endl;
18             break;
19         }
20         for(int i=0;i<3;++i){
21             ll a=num*x[i];
22             if(mp[a]==0){//对取过的丑数进行标记
23                 q.push(a);
24                 mp[a]++;
25             }
26         }
27         cnt++;
28     }
29     return 0;
30 }
View Code

POJ

 1  #include<iostream>
 2 #include<cstdlib>
 3 #include<queue>
 4 #include<map>
 5 #include<algorithm>
 6 using namespace std;
 7 typedef long long ll;
 8 int main()
 9 {
10     ios::sync_with_stdio(false);
11     ll num=1;
12     ll ugly[1510];//打表存数,对于询问直接输出
13     priority_queue<ll,vector<ll>,greater<ll> > q;
14     map<ll,ll> mp;
15     int x[3]={2,3,5},cnt=1;
16     q.push(num);
17     mp[num]++;
18     while(!q.empty())
19     {
20         num=q.top();
21         q.pop();
22         ugly[cnt]=num;
23         if(cnt==1500)
24             break;
25         for(int i=0;i<3;++i){
26             ll a=num*x[i];
27             if(mp[a]==0){
28                 q.push(a);
29                 mp[a]++;
30             }
31         }
32         cnt++;
33     }
34     int n;
35     while(cin>>n&&n)
36         cout<<ugly[n]<<endl;
37     return 0;
38 }
View Code

 

转载于:https://www.cnblogs.com/SCaryon/p/7375069.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值