丑数ugly_number

丑数是指因子只有2,3,5的数字,特别的1被认为是丑数;寻找第1500个丑数按照一般的思路就是,暴力模拟,不断的用循环变量去除以2,3,5;如果能除尽就让计数器++;直到计数器==1500,就输出这个值;这样做确实可以但是会很浪费时间

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
int ugly(int);
int main ()
{
	int cnt=0;
	int res;
	for (int i=1;cnt!=1500;i++)
	{
		if (ugly(i))
		{
			res = i;
			cnt++;
		}
	}
	cout << res;
    return 0;
}
int ugly (int num)
{
	int flag=0;
	while(num)
	{
		while(num%2==0) num/=2;
	 	while(num%3==0) num/=3;
	 	while(num%5==0) num/=5;
	 	//如果是丑数的话到最后num的值一定是1;
	 	if(num==1)
	 	{
	 		flag=1;
	 		break;
	    }
	    else
		{
		  flag=0;
		  break;
	    }
	}
	return flag;

}

在这里插入图片描述
我的电脑上花了有16秒QAQ,timelimted的既视感有没有,接下来就要开始优化了(这个思路也是我在网上看的觉得很好想写下来,绝对不是复制过来的 ,侵删)
丑数的因子只有2,3,5之后的丑数一定是当前的丑数乘以2,3,5后最小的并且是不重复的那个;
那么关键点来了:构造三个队列,分别放入2,3,5,然后寻找最小值,把队前的与最小值相同的数据出队并删除,然后再给后面的包括本身在内的队列入队一个元素(如果给所有的队列都入队元素会出现同的队列内存在相同的元素);元素是:出队元素乘以这个队列最开始的值(2,3,5)

用数据描述就是

有三个队列 n1 n2 n3;初始放入元素2,3,5
定义 minval;
n1 : 2
n2 : 3
n3 : 5
minval = 2;
第一次
n1 : 4
n2 : 3 6
n3 : 5 10
minval = 3;
第二次
n1 : 4 8
n2 : 6 12
n3 : 5 10 20
minval = 4;

一直这样循环下去,minval的值就是丑数,可以用一个数组保存下来,也可以直接搞一个计数器等到了第1500个的时候直接输出就好了

#include<iostream>
#include<stack>
#include<queue>
#include<cstdio>
#include<algorithm>
using namespace std;
int find_ugly_number (int n);
int main ()
{
	int num = find_ugly_number(1500);
	
	printf ("The 1500'th ugly number is <%d>.",num);

}
int find_ugly_number (int n)
{
	if (n==1) return 1;
	queue <int > q1,q2,q3;
	int minval;
	q1.push(2);
	q2.push(3);
	q3.push(5);
	while (n-- > 1)
	{
		minval = min (min(q1.front(),q2.front()),q3.front());
		//cout << minval << ' ';
		if (minval == q1.front())
		{
			q1.pop();
			q1.push(minval*2);
			q2.push(minval*3);
			q3.push(minval*5);
		}else if (minval == q2.front())
		{
			q2.pop();
			q2.push(minval*3);
			q3.push(minval*5);
		}
		else
		{
			q3.pop();
			q3.push(minval *5);
		}

	}

	return minval;
}

在这里插入图片描述
暴力解决的时间16秒,用上数据结构和算法后时间只有0.02秒,这就输算法的魅力

最后在放一个水过的方法

题目不是让输出第1500个丑数么,直接暴力模拟,求出答案,写在源代码是直接cout<<"859963392";多简单 QAQ;

如果没过的话就在结尾输出一个回车(一个WA了八遍的人的经验)
写代码上瘾句子结尾老爱加;;;;;;
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值