Time Limit: 10 second
Memory Limit: 2 MB
问题描述 完全数又称完数、完美数、完备数,是一些特殊的自然数,它所有真因子(即除自己以外的因子)的和等于它本身。例如:6=1+2+3,6是一个完数。 至今为止,人类共发现了46个完数,由于简单类型的数据范围有限,所以仅能求出前n(n<=8)个完数。
Input
一个整数n
Output
有n行,输出前n个完数,每个数占一行
Sample Input
3
Sample Output
6 28 496
【题解】
如果直接暴力求解 会超时。10s都不够用。
这题考的是数论。有点变态。
完全数和梅森数素数有一个一一对应的关系
即对于一个梅森素数mp = 2^p - 1,必有 一个完全数 2^(p-1) * mp;
平台很奇怪,我用lld输出,输出来的结果是对的,在平台上却显示错误,后来我没用lld输出,一位一位地存入int数组中,再一位一位地输出。
【代码】
#include <cstdio> #include <cmath> const int maxn = 1000,maxl = 1000; int num = 0,n; void input_data() { scanf("%d",&n); } bool can(long long x) //判断x是否为质数 { if (x < 2) return false; int d = sqrt(x); for (int i = 2;i <=d;i++) if ( (x % i) == 0) return false; return true; } void get_ans() { int p = 1; while (num != n) //如果还没有找到所需的数目就继续找。 { long long int mp = 1; for (int i = 1;i <= p;i++) //算2^p mp = mp*2; mp--; if (can(mp)) //如果这个梅森数是质数 { num++; long long int t = 1; for (int i = 1;i <= p-1;i++) t = t * 2; t = t * mp; //算出完全数 int temp[maxl]; //把这个完全数一位一位地存入int数组; int i = 0; while (t > 0) { temp[++i] = t % 10; t = t /10; } for (int j = i;j >=1;j--) //再一位一位输出 printf("%d",temp[j]); printf("\n"); } p++; } } int main() { input_data(); get_ans(); return 0; }