小米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類型。終於順利通過。。。