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类型。终于顺利通过。。。

在这里插入图片描述

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