1. 程式人生 > >【 OJ 】 HDOJ1058 18年12月22日20:00 [ 50 ]

【 OJ 】 HDOJ1058 18年12月22日20:00 [ 50 ]

這題找規律我想了很多試了有的感覺很煩,參考了人家的思路很....OJBnice,所以我按照人家的思路寫了一遍。

這題就是求醜數,醜數最小的因子由2,3,5,7組成,1 被定義為最小丑數

首先很重要的一點要說下,醜數一定是由醜數乘醜數所得  ( =  =.)!! 醜數定義說的很明確因子只含有2,3,5,7

2357可以理解為這個是醜數的最小倍數,假設一個醜數x存在,那麼當前醜數x可以產生的醜數一定由乘2357產生,當前醜數x產

生的最小丑數不一定是當前序列所需要的....假設目前序列為 1 2 3 4 5 6 ,下一個需要的最小丑數為7(由1*7產生),但是6可以

產生的最小丑數一定是 6*2=12,但是12並不是當前序列所需要的最小丑數,就這個意思

所以解決方法就是:1和2357相乘會得到4個數(這4個數也是1所能產生的最小丑數),拿到4箇中最小的一個1*2,2已經被放進

序列,說明1*2已經用完了,但是剩下的357遲早會用到,不動它們。這時候讓2的指標index2去指向序列中的2的位置,因為2放

進了序列,這時候2也能產生4個最小的醜數,其他的不可能用到,因為2*(3.5.7)一定大於1*(3.5.7),但是2*2可能會被用到。

所以從2*2和1*3和1*5和1*7中選擇一個最小的數字,並放入序列,然後移動指標,重複N-1次得到第N個醜數

注:其中2*3 和3 *2因為都等於6所以說明序列2 和序列3 產生的都被使用,所以2 和 3 的指標index2 index3都需要指向序列的下一個

下面是AC程式碼:

# include<iostream>
# include<algorithm>
//# include<Windows.h>
# define NMAX 10000
using namespace std;
int Res[NMAX] = {1};
int MIN(int a, int b, int c,int d) {
	return min((min(a, b)), (min(c, d)));//返回最小值
}
int main()
{
	//long start_time = GetTickCount(); //獲取此程式段開始執行時間
	int index, index2, index3, index5, index7;
	index2 = index3 = index5 = index7 = 0;//初始化為0
	index = 1;
	int n; cin >> n;
	int temp;
	while (n) {
		while (index < n) {
			temp = MIN(Res[index2] * 2, Res[index3] * 3, Res[index5] * 5, Res[index7] * 7);
			if (temp == Res[index2] * 2)index2++;
			if (temp == Res[index3] * 3)index3++;
			if (temp == Res[index5] * 5)index5++;
			if (temp == Res[index7] * 7)index7++;
			Res[index++] = temp;
		}
		int m = n % 100;
		if(m==11||m==12||m==13)
			printf("The %dth humble number is %d.\n", n, Res[n-1]);
		else if(n%10==1)
			printf("The %dst humble number is %d.\n", n, Res[n-1]);
		else if(n%10==2)
			printf("The %dnd humble number is %d.\n", n, Res[n-1]);
		else if(n%10==3)
			printf("The %drd humble number is %d.\n", n, Res[n-1]);
		else 
			printf("The %dth humble number is %d.\n", n, Res[n-1]);
		//n帶 11 12 13為th 剩下 1 st 2 nd 3 rd 
		cin >> n;
	}
//	long end_time = GetTickCount(); //獲取此程式段開始執行時間
//	cout << "程式段執行時間:" << (end_time - start_time) << "ms!" << endl; //差值即執行時間
	system("pause");
	return 0;
}