您的位置:首页 > 理论基础 > 数据结构算法

oj之路(第三天)(续)

2014-03-19 09:25 169 查看

这是一道让我收益不少的题目,这道题目自己没有遇到过,是通过一个老师讲解得来的。

==========================================================================================================

题目描述:

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. 

Given the integer n,write a program to find and print the n'th ugly number. 

输入格式

Each line of the input contains a postisive integer n (n <= 1500).Input is terminated by a line with n=0.

输出格式

For each line, output the n’th ugly number .:Don’t deal with the line with n=0.

输入样例

1

2

9

0

输出样例

1

2

10

==========================================================================================================

思考过程:
这里我想继续吐槽“记忆搜索”思想的体现-----用一个算好的数组来为以后要求的数据给出直接的答案,因为不保存计算结果而每次都要重新计算是很耗时的。
这里的想法就是通过一次计算把前面1500个ugly number给计算出来保存进数组里面,为以后查询提供答案:(这里有两种“思想”)
①打表法:先写一个直接计算出前1500个ugly number的程序---很耗时,然后把这1500个ugly number记下来,然后在写解决问题的程序,把这1500个ugly number
用在这个程序里面,用数组保存,为后来的查询直接提供答案。
打表法使用条件:
程序要求的数据范围不是很大(这里是1500以内的ugly number),可以通过计算的得出全部情况的结果。
②构造法:通过一定的构造规则(这里是ugly number(从1开始构造)或乘以2、或3、或5得出新的ugly number,然后比较得出最小的ugly number,再重复该规则构造,
直到把1500个ugly number全部算出来),把所有的数据范围内的情况全部算出来保存好,为以后查询服务。
构造法使用条件:
构造时一定要遵循尽量不要重复构造的相同的数据,实在无法避免就想方法消除重复。
例如这道题:1乘以2、3、5得出2、3、5,则2是最小的ugly number,那么2继续乘以2、3、5得出4、6、10,则在3、4、5、6、10里面最小的ugly number是3,那么
此时的3就不能乘以2,只能乘以3、5得出9、15,因为乘以2的话得出6跟前面的ugly number集合元素重复了·····

==========================================================================================================

源代码:(用构造法来解)

#include <iostream>
#include <queue>
#include <functional>
using namespace std;
typedef pair<unsigned long, int> node;

int main()
{
unsigned long uglyNumber[1500];//又是“记忆搜索”,为以后每次查询提供答案
priority_queue< node, vector<node>, greater<node> > queue;
queue.push(make_pair(1, 2));
for (int i = 0; i < 1500; ++i) {
node t = queue.top();
queue.pop();
switch (t.second) {
case 2:
queue.push(make_pair(t.first * 2, 2));
case 3:
queue.push(make_pair(t.first * 3, 3));
case 5:
queue.push(make_pair(t.first * 5, 5));
}
uglyNumber[i] = t.first;
}
int n;
cin >> n;
while (n > 0) {
cout << uglyNumber[n - 1] << endl;
cin >> n;
}
return 0;
}

==========================================================================================================
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息