Time Limit: 1 SecMemory Limit: 128 MB
Submit: 130Solved: 82
[Submit][Status][Web Board]
Description
一个数是否完美是这样定义的,如果这个数的素数因子只有2,3,5,7,那么这个数就是完美的.
显而易见前面几个完美的数为1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 27, ...
你能告诉我第n个完美的数是多少嘛?
Input
多组测试数据.每组数据的第一行包含一个正整数n(1<= n<=5842).
Output
对于每组测试数据输出第n个完美的数
Sample Input
1
11
5842
Sample Output
1
12
2000000000
求第n个丑数 - HanSion.Z - CSDN博客
ZCMU-1178-完美的数 - ZCMUCZX的博客 - CSDN博客
zcmu-1178: 完美的数(乘数累加) - 欢迎访问方偲的博客 - CSDN博客
求丑数:(拓展)
解题思路一:暴力枚举法。
1.首先,我们应该了解什么是因子。所谓的数m是数n的因子,是指数n可以被数m整除,既n%m=0。
2.要判断一个数是不是为丑数。就要判断这个数除了能被2、3、5整除,是否可以被其他数字整除,能则不是,不能则是。也就是如果这个数可以被2整除,我们把它连续除以2;如果这个数可以被3整除,我们把它连续除以3;如果这个数可以被5整除,我们把它连续除以5。
3.现在我们已经知道怎么去判断一个数是否为丑数,那么要求的第1500个丑数,我们只需要从0开始遍历,如果这个数是丑数,则修改循环变量循环继续,如果不是,则直接让循环继续,总共计算1500次就可以求出来了。
解决思路二:(空间换时间)
1.假设前面存在一个有序的丑数数组,要求下一个有序的丑数。一个丑数只能被2、3、5整除,那么说明下一个丑数必然等于前面某一个丑数乘以2、3或者5
2.第一个丑数必然是1,假如现在求第二个丑数并且要求和前面的丑数按照递增有序要怎么求?1*2=2,1*3=3,1*5=5,显然要有序,必然是它们中最小的那个
3.假设现在要求第3个丑数,1*2<3, 1*3<=3, 1*5=5, 2*2=4, 2*3=6, 2*5=10, 显然第3个丑数为4,但是我们发现每次都如果从1开始,有很多小于第三个丑数的值存在,我们应该在上一次求丑数的时候把这个位置记录下来,下次就可以直接求大于上一个丑数的值了。
附上代码:
//求三个值中的最小值
int Min(int n1, int n2, int n3)
{
int mid = n1 > n2 ? n2 : n1;
return mid > n3 ? n3 : mid;
}
//求第N个丑数
int GetNUglyNum_op(int index)
{
if (index <= 0)
return 0;
//开辟index个辅助空间
int *pUglyNum = (int *)malloc(sizeof(int)*index);
pUglyNum[0] = 1;//第一个丑数为1
int nextindex = 1;//下一个丑数的下标
//记录上次求丑数时大于那个丑数的位置
int *pMutiply2 = pUglyNum;
int *pMutiply3 = pUglyNum;
int *pMutiply5 = pUglyNum;
while (nextindex < index)
{
//下一个丑数是3个乘积中的最小值
int minvalue = Min(*pMutiply2 * 2, *pMutiply3 * 3, *pMutiply5 * 5);
pUglyNum[nextindex] = minvalue;
//找到小于等于有序数组中最后一个丑数的位置(避免计算比上一个丑数小的值)
while (*pMutiply2 * 2 <= pUglyNum[nextindex])
pMutiply2++;
while (*pMutiply3 * 3 <= pUglyNum[nextindex])
pMutiply3++;
while (*pMutiply5 * 5 <= pUglyNum[nextindex])
pMutiply5++;
nextindex++;
}
int nUglyNum = pUglyNum[nextindex - 1];
free(pUglyNum);
pUglyNum = NULL;
return nUglyNum;
}
原文:https://blog.csdn.net/hansionz/article/details/82722357
本题AC代码:------这里还没出现
本题TE代码:-------
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
int c[4]={2,3,5,7};
vector
priority_queue
set
void f(){
int i,j;
pq.push(1);
s.insert(1);
for(i=1;i<=5842;i++)
{
ll x=pq.top();//队首 当前最小的数,分别和2 3 5 7 想乘
pq.pop();//当前使用这个数,所以从队列中删掉
a.push_back(x);//可用的数,存到数组中
for(j=0;j<4;i++)
{
ll x2=x*c[j];
if(!s.count(x2))//是否有重复的元素
{
s.insert(x2);
pq.push(x2); //添加到队列尾
}
}
}
}
int main()
{
f();
int n;
while(~scanf("%d",&n))
{
printf("%lld\n",a[n-1]);
}
return 0;
}