oj之路(第三天)(续)

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

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

题目描述:

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;
}

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值