hdu 1058 Humble Numbers

31 篇文章 0 订阅

Problem

acm.hdu.edu.cn/showproblem.php?pid=1058

题意

找出从小到大第 n 个因子(除了 1 和本身)只有 2、3、5、7 的数。即第 n 个 num = 2^a * 3^b * 5^c * 7^d 的数(据说叫丑数)。

分析

从 1 开始,乘2、3、5、7中的随便一个,就产生 4 个这样的数;从这 4 个数出发,分别乘 2、3、5、7,再产生更多的数…依此类推产生所有这样的数。

但要从小到大排序。可以想出,下一个最小的丑数肯定是某几个之前的丑数乘 2 或 3 或 5 或 7 产生的。

按上面的产生方法,每丑数乘 2 可以产生新的一个新的丑数,其它也是。

将丑数按升序存在一个数组 ugly [] 里,用 4 个变量 a、b、c、d 分别记录一个下标,表示 2、3、5、7 下一次要跟哪个之前的丑数相乘产生新丑数。

产生的 4 个新丑数就是:2 * ugly[a]、3 * ugly[b]、5 * ugly[c]、7 * ugly[d]。它们是可能的下一个最小的丑数。

从它们之间找那个最小的加到数组尾,然后判断是由哪个因子产生的,让它的下标加一(指向下一个还没跟它相乘产生新丑数的丑数)。

它们这些产生的新丑数中,可能有重复,所以可能一次要移动多个下标。

Source code

#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 5842;

int ugly[N+1] = {0, 1};

int main()
{
	for(int i=2,two=1,three=1,five=1,seven=1; i<=N; ++i)
	{
		ugly[i] = min(
			min(2 * ugly[two], 3 * ugly[three]),
			min(5 * ugly[five], 7 * ugly[seven])
		);
		// 可能新丑数有重复,不能加 else
		if(ugly[i] == 2 * ugly[two])
			++two;
		if(ugly[i] == 3 * ugly[three])
			++three;
		if(ugly[i] == 5 * ugly[five])
			++five;
		if(ugly[i] == 7 * ugly[seven])
			++seven;
	}
	for(int n; scanf("%d", &n), n; )
	{
		printf("The %d", n);
		if(n % 10 == 1 && n % 100 != 11)
			printf("st");
		else if(n % 10 == 2 && n % 100 != 12)
			printf("nd");
		else if(n % 10 == 3 && n % 100 != 13)
			printf("rd");
		else
			printf("th");
		printf(" humble number is %d.\n", ugly[n]);
	}
	return 0;
}
这居然是 dp…看来我对 dp 的理解还是太肤浅

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值