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

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章