725. 完全数 - AcWing题库https://www.acwing.com/problem/content/727/
方法一
Actually
其实 100000000内的完全数没有几个
Good!
数学部分
100000000
内的完全数有且仅有 6,28,496,8128,33550336 这五个.根据上述内容, 这道题可以直接 O(1)
完全数比较重要的几个性质
所有完全数都是三角形数
目前截止发现的所有完全数都以 6 或 28 结尾
到现在为止,数学家们一共发现了 48 个完全数,且 48个完全数全部是偶数
如果有人们没有找到的奇完全数,则它一定可以写成 +1或 +9的形式,而且 p是素数
奇完全数一定大于
完全数的约数的倒数之和为调和数
完全数可以表示成连续奇数的立方和
完全数可以表示成 2的连续自然数的次幂之和,且这些自然数的数量必定是素数。
完全数计算法
若 −1是素数(亦称其为梅森素数),则 ∗(−1)是完全数.
#include <bits/stdc++.h>
using namespace std;
int main() {
int tt;
cin >> tt;
while (tt--) {
int n;
cin >> n;
if (n == 6 || n == 28 || n == 496 || n == 8128 || n == 33550336)
cout << n << " is perfect" << endl;
else cout << n << " is not perfect" << endl;
}
return 0;
}
如果用两个循环会超时。
方法二
使用数学函数,sqrt 作为限制循环次数的条件,而另外一个约数则由输入数x除以当前的循环的约数,即可求得另一约数 注:此处需要考虑等于的情况,比如16 开根号是4 4也是约数 优化过后,复杂度为O(10^4*100) 100万 完全hold住
以后遇到此类题,诸如质数、完全数 等定义中带有约数、需要整除,优化方面皆可朝开平方处思考
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n,x,sum=0;
cin >> n;
for(int i=0;i<n;i++)
{
cin >> x;
if(x==1) cout << x << " is not perfect" << endl;
else
{
sum+=1;
for(int j=2;j<=sqrt(x);j++)
{
if(x%j==0)
{
int y=x/j;
if(y==j) sum=sum+j;
else sum=sum+j+x/j;
}
}
if(sum==x) cout << x << " is perfect" << endl;
else cout << x << " is not perfect" << endl;
}
sum=0;
}
return 0;
}