mioj第N個醜數

小米oj

這個題目的數據比較刁鑽。。。

第N個醜數


描述
把只包含因子2、3和5的數稱作醜數(Ugly Number)。例如6、8都是醜數,但14不是,因爲它包含因子7。 習慣上我們把1當做是第一個醜數。求按從小到大的順序的第N個醜數。


輸入
輸入一個正整數N,0<N<10000


輸出
輸出一個正整數S,S爲第N個醜數


解題思路

輸出
首先嚐試一種比較常規的做法,對從1開始的每個數進行遍歷,查看是不是一個醜數,具體做法就是,把這個數分別整除2,3,5,知道不能除爲止。最後剩下的數如果是1,那麼這個數就是醜數。具體代碼如下

int hxnb(int n)//輸入是n判斷n是不是醜數
{
	while (n % 2==0)
		n /= 2;
	while (n % 3==0)
		n /= 3;
	while (n % 5==0)
		n /= 5;
	if (n == 1)
		return 1;
	else
		return 0;
}

然而這種做法時間複雜度爲n*logn所以時間所以時間上很長,抱着僥倖的心理。結果。。。。。。。果然不行。。。顯示超時。。。
然後就不得不用另一種辦法。每一個新出現的醜數一定是前面的醜數乘2,3或者是5來得到的,我們可以只找第一個比現在最大丑數大的醜數,不用去遍歷哪些一定不是醜數的,時間上能夠得到不小的提升。具體實現如下


long long hxnb(long long n)//第n個醜數是多少
{
	//int * ugly = (int*)calloc(3000,sizeof(int));
	long long ugly[6000] = {};
	ugly[0] = 1;//第一個醜數爲1
	int index2 = 0;
	int index3 = 0;
	int index5 = 0;
	int index = 1;
	while (index<n)
	{
		long long val = min_h(ugly[index2] * 2, ugly[index3] * 3, ugly[index5] * 5);
			if (val == ugly[index2] * 2)
				index2++;
			if (val == ugly[index3] * 3)
				index3++;
		   if (val == ugly[index5] * 5)
		        index5++;
		ugly[index++] = val;
	//	printf("val =%d   %d %d  %d\r\n", val,index2,index3,index5);
	}
//	free(ugly);
	return ugly[index-1];
}

這裏有一個細節,一開始全部用的int,然而int的範圍是-2147483648 ~ 2147483647,所以當N是1000多的時候就根本不行。。。。迫不得已,所以的數據選用long long類型。終於順利通過。。。

在這裏插入圖片描述

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