九度OJ-题目1214:丑数
2015-06-10 11:42
253 查看
题目链接地址:
九度OJ-题目1214:丑数
题目描述:
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。
习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
输入:
输入包括一个整数N(1<=N<=1500)。
输出:
可能有多组测试数据,对于每组数据,
输出第N个丑数。
样例输入:
3
样例输出:
3
解题思路:
这道题我的想法是从2开始依次遍历每个整数,如果某个整数只包含因子2、3和5,就可以认为它是丑数,这个方法显然太暴力了,肯定会超时的。于是上网搜了一下此题的解法,发现网上的解法都大致一样:因为除1之外,后面的丑数都只包含2,3,5这3个因子,可以由2,3,5这3个因子与已有的丑数相乘推算出新的丑数。以下是推算的具体过程:
(1) 根据3个因子将候选丑数分成3类:由与2相乘得到的候选丑数,由与3相乘得到的候选丑数,由与5相乘得到的候选丑数;
(2) 每次都从这3类候选丑数中选择一个最小值做为新的丑数,并且更新相应类的候选丑数。
举个栗子,以下是求第7个丑数的过程:
1) 第1个丑数是1;
2) 将2,3,5分别与第1个丑数1相乘,此时候选丑数是{2,3,5},所以第2个丑数是2,此时丑数序列为[1,2];
3) 将2与第2个丑数2相乘得4;3,5分别与第1个丑数1相乘,此时候选丑数是{4,3,5},所以第3个丑数是3,
此时丑数序列为[1,2,3];
4) 将2与第2个丑数2相乘得4,将3与第2个丑数2相乘得6,将5与第1个丑数1相乘得5,此时候选丑数是{4,6,5},
所以第4个丑数是4,此时丑数序列为[1,2,3,4];
5) 将2与第3个丑数3相乘得6,将3与第2个丑数2相乘得6,将5与第1个丑数1相乘得5,此时候选丑数是{6,6,5},
所以第5个丑数是5,此时丑数序列为[1,2,3,4,5];
6) 将2与第3个丑数3相乘得6,将3与第2个丑数2相乘得6,将5与第2个丑数2相乘得10,此时候选丑数是{6,6,10},
所以第6个丑数是6,此时丑数序列为[1,2,3,4,5,6];
7) 将2与第4个丑数4相乘得8,将3与第3个丑数3相乘得9,将5与第2个丑数2相乘得10,此时候选丑数是{8,9,10},
所以第7个丑数是8,此时丑数序列为[1,2,3,4,5,6,8]。
AC代码如下:
九度OJ-题目1214:丑数
题目描述:
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。
习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
输入:
输入包括一个整数N(1<=N<=1500)。
输出:
可能有多组测试数据,对于每组数据,
输出第N个丑数。
样例输入:
3
样例输出:
3
解题思路:
这道题我的想法是从2开始依次遍历每个整数,如果某个整数只包含因子2、3和5,就可以认为它是丑数,这个方法显然太暴力了,肯定会超时的。于是上网搜了一下此题的解法,发现网上的解法都大致一样:因为除1之外,后面的丑数都只包含2,3,5这3个因子,可以由2,3,5这3个因子与已有的丑数相乘推算出新的丑数。以下是推算的具体过程:
(1) 根据3个因子将候选丑数分成3类:由与2相乘得到的候选丑数,由与3相乘得到的候选丑数,由与5相乘得到的候选丑数;
(2) 每次都从这3类候选丑数中选择一个最小值做为新的丑数,并且更新相应类的候选丑数。
举个栗子,以下是求第7个丑数的过程:
1) 第1个丑数是1;
2) 将2,3,5分别与第1个丑数1相乘,此时候选丑数是{2,3,5},所以第2个丑数是2,此时丑数序列为[1,2];
3) 将2与第2个丑数2相乘得4;3,5分别与第1个丑数1相乘,此时候选丑数是{4,3,5},所以第3个丑数是3,
此时丑数序列为[1,2,3];
4) 将2与第2个丑数2相乘得4,将3与第2个丑数2相乘得6,将5与第1个丑数1相乘得5,此时候选丑数是{4,6,5},
所以第4个丑数是4,此时丑数序列为[1,2,3,4];
5) 将2与第3个丑数3相乘得6,将3与第2个丑数2相乘得6,将5与第1个丑数1相乘得5,此时候选丑数是{6,6,5},
所以第5个丑数是5,此时丑数序列为[1,2,3,4,5];
6) 将2与第3个丑数3相乘得6,将3与第2个丑数2相乘得6,将5与第2个丑数2相乘得10,此时候选丑数是{6,6,10},
所以第6个丑数是6,此时丑数序列为[1,2,3,4,5,6];
7) 将2与第4个丑数4相乘得8,将3与第3个丑数3相乘得9,将5与第2个丑数2相乘得10,此时候选丑数是{8,9,10},
所以第7个丑数是8,此时丑数序列为[1,2,3,4,5,6,8]。
AC代码如下:
#include<stdio.h> #define MAX 1501 /** * 返回3个数中的最小值 * @param long long a 第一个数 * @param long long b 第二个数 * @param long long c 第三个数 * @return long long 三个数中的最小值 */ long long getMinOfThreeNumbers(long long a,long long b,long long c) { long long min = a; if(b < min) min = b; if(c < min) min = c; return min; } /** * 获取前n个丑数 * @param longlong uglyNumber[] 用于存放丑数的数组 * @return void; */ void getUglyNumbers(long long uglyNumber[],int n) { int i; int indexOfUglyNumber = 1; // 丑数数组对应的下标 int indexOfTwo = 1; // 与2对应的乘数的在丑数数组中的下标 int indexOfThree = 1; // 与3对应的乘数的在丑数数组中的下标 int indexOfFive = 1; // 与5对应的乘数的在丑数数组中的下标 long long curUglyNumber; // 当前生成的丑数 long long curUglyNumberOfTwo; // 由与2相乘得到的丑数 long long curUglyNumberOfThreee; // 由与3相乘得到的丑数 long long curUglyNumberOfFive; // 由与5相乘得到的丑数 uglyNumber[1] = 1; // 第1个丑数是1 for(i = 2;i <= 1500; i++) { curUglyNumberOfTwo = 2 * uglyNumber[indexOfTwo]; curUglyNumberOfThreee = 3 * uglyNumber[indexOfThree]; curUglyNumberOfFive = 5 * uglyNumber[indexOfFive]; // 从当前3个候选中,选择最小的一个做为新的丑数 curUglyNumber = getMinOfThreeNumbers(curUglyNumberOfTwo,curUglyNumberOfThreee,curUglyNumberOfFive); uglyNumber[++indexOfUglyNumber] = curUglyNumber; // 更新各个乘数的下标 while(2 * uglyNumber[indexOfTwo] <= curUglyNumber) { indexOfTwo++; } while(3 * uglyNumber[indexOfThree] <= curUglyNumber) { indexOfThree++; } while(5 * uglyNumber[indexOfFive] <= curUglyNumber) { indexOfFive++; } } } /** * 打印第n个丑数 * @param long long uglyNumber[] 存储丑数的数组 * @param int n n表示打印第n个丑数 * @return void */ void printNthUglyNumber(long long uglyNumber[],int n) { printf("%lld\n",uglyNumber ); } int main() { long long uglyNumber[MAX]; // 存放丑数 int n; getUglyNumbers(uglyNumber,1500); // 获取前1500个丑数 while(EOF != scanf("%d",&n)) { printNthUglyNumber(uglyNumber,n); } return 0; } /************************************************************** Problem: 1214 User: blueshell Language: C++ Result: Accepted Time:10 ms Memory:1020 kb ****************************************************************/
相关文章推荐
- java远程调.net webservice例子
- 添加弹出菜单,并动态设置菜单项变灰
- adb logcat命令查看并过滤android输出log
- 鸿博信通语音调度解决方案
- MAC中sublime text 编译 Lua
- androidの亮屏,灭屏,解锁广播使用
- LDAP概念和原理
- SecureCRT连接Linux显示Mysql记录中文乱码
- UIStepper
- Objective-C 实现2048算法类
- 搜索意图三分法:用户搜索行为及其意图浅析
- TIME_WAIT状态
- 类和结构体一
- ACTION_CANCEL事件的触发条件
- 3DMax的OFusion插件的使用问题
- MySqlDataReader在Using中使用
- 无法进入KindEditor.ready(function(){})的解决办法
- 简介JavaScript中的getUTCFullYear()方法的使用
- Axure画Android原型
- Bootstrap3的栅格化样式