首页 > 试题广场 >

完全数计算

[编程题]完全数计算
  • 热度指数:153473 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
\hspace{15pt}完全数,又称完美数或完备数,是一些特殊的自然数。它所有的真因子(即除了自身以外的约数)之和恰好等于它本身。

\hspace{15pt}现在,你需要计算 1n 之间完全数的个数。

输入描述:
\hspace{15pt}输入一个整数 n \left(1 \leqq n \leqq 5 \times 10^5\right)


输出描述:
\hspace{15pt}输出一个整数,代表区间内完全数的个数。
示例1

输入

1000

输出

3

说明

\hspace{15pt}第一个完全数是 6,因为 6 的约数有 1, 2, 3, 6,去除本身后,剩余约数之和为 1+2+3=6
\hspace{15pt}第二个完全数是 28,因为 28 的约数有 1, 2, 4, 7, 14, 28,去除本身后,剩余约数之和为 1+2+4+7+14=28
import java.util.Scanner;
public class Main {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()) {
            int n = sc.nextInt();
            int cnt = 0;
            while((n--)>1) {
                int number = 0;
                for(int i=1; i<n; i++) {
                    if(n%i==0) {
                        number += i;
                    }
                }
                if(n == number) {
                    cnt++;
                }
            }
            if(cnt != 0)
                System.out.println(cnt);
            else
                System.out.println(-1);
        }
    }
}

发表于 2018-10-06 19:01:15 回复(0)
#include <bits/stdc++.h>
 using   namespace std;
int fun(int n)
{
    int cnt=0;
    if(n>500000 || n<=0) return -1;
    else
    {
        
        for(int i=2;i<=n;i++)
        {
            int sum=0;
            for(int j=2;j<sqrt(i);j++)
            {
                if(i%j==0)
                {
                    if(i/j==j) sum+=j;
                    else
                    {
                        sum+=j;
                        sum+=(i/j);
                    }
                }
            }
            if(sum+1==i) cnt++;
        }
    }
    return cnt;
}
int main()
{
    int n;
    while (cin >>n)
    {
        cout<<fun(n)<<endl;
    }
    system("pause");
    return 0;
}

发表于 2018-08-20 14:13:46 回复(0)
#include <iostream>
#include <math.h>
#include <string.h>
using namespace std;

int main(){
    
    int n;
    int count = 0;
    
    int tmp[100];
    while (cin >> n){
        
        if (n > 0 && n <= 50000){
            int a = 0;
            while (n > 1){
                memset(tmp, 0, sizeof(tmp));
                for (int i = 2; i <= sqrt(n); i++)  //降低复杂度
                {
                    if (n % i == 0)
                    {
                        if (n % i == i)
                        {
                            tmp[count++] = i;
                        }
                        else
                        {
                            tmp[count++] = i;
                            tmp[count++] = n / i;
                        }
                    }
                }

                int sum = 1;
                for (int i = 0; tmp[i]; i++)
                {
                    sum += tmp[i];
                }
                if (sum == n)
                {
                    a++;
                }
                n--;
                count = 0;
            }
            cout << a << endl;
        }
        else
        {
            return -1;
        }
    }
    
    return 0;
}
发表于 2017-08-18 23:26:02 回复(0)
#include<stdio.h>
#include<math.h>
int main() {
int num;
while(~scanf("%d", &num)){
    if(num==1){printf("0\n");break;}
    int count = 0;
    for(int i=2; i<=num; i++){
        int sum = 1,root = sqrt(i); // 求约数遍历到根值即可
        for(int j=2; j<=root; j++){
            if(i%j==0){
                sum +=j; //与约数j相加
                if(i!=root) //防止两个相同的约数重复计算
                    sum +=(i/j); //与约数j对应点另一个约数相加
            }
        }
        if(sum == i)count++;
    }
    printf("%d\n", count);
}
}

发表于 2022-03-29 20:32:28 回复(0)
一遍过的,可能有点麻烦,之前遇到过类似的,直接分享了思路:
while True:
    try:
        n = int(input())
        l_n = []  # 用于储存不大于n的完全数
        for i in range(5, n+1):     #最小的完全数是6 = 1+2+3,所以从5开始,循环是为了判断每个不大于n的数是不是完全数
            l_f = []              # 用于储存每次循环的 i 的因子
            for j in range(2, int(i**0.5)+1):     # 找i不含自身的因子,i**0.5 相当于 i开方
                if i % j == 0:               # 如果j 是 i 的因子 ,就把j 和 i//j储存起来
                    l_f.append(j)
                    l_f.append(i // j)
            if i == 1 + sum(l_f):        # 判断 i是否是是完全数,注意,加上1 是因为,储存因子的列表不包含1
                l_n.append(i)             # 是完全数,就存起来
            l_f.clear()                    # 这一步很重要,清空储存因子的列表,因为每次判断i是不是完全数都会向该列表添加因子(除非i是质数)
        print(len(l_n))              # 题目要求输出 完全数的个数,即 l_n 列表的长度
    except:
        break


发表于 2022-01-04 09:42:16 回复(0)
import java.util.*;
public class Main{
    public static boolean isPerfectNumber(int n){
        //判断是否为完美数
        boolean b = false;
        int sum = 0;
        for(int i =1;i<n;i++){
            if(n%i == 0){
                sum = sum+i;
            }
        }
        if(sum == n){
            b = true;
        }
        return b;
    }
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int count = 0;//完美数的数量
            int n = sc.nextInt();
            for(int i =1;i<=n;i++){
                if(isPerfectNumber(i)){
                    count++;
                }
            }
            System.out.println(count);
        }
    }
}
发表于 2022-01-03 21:00:09 回复(0)
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNextInt()){
            int n = sc.nextInt();
            int count = 0;
            for(int i = 1; i <= n;i++){
                if(isPerfect(i)){
                    count++;
                }
            }
            System.out.println(count);
        }
    }
    public static boolean isPerfect(int num){
        int result = 0;
        for(int i = 1; i <= num/2;i++){
            if(num % i==0 && num!=i){
                result += i;
            }
        }
        if(result == num){
            return true;
        }
        return false;
    }
}

发表于 2021-11-30 10:53:50 回复(0)
import java.util.*;
public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()) {
            int n = sc.nextInt();
            int count = 0;
            for(int i = 2; i <= n; i++) {
                if(isP(i)) count++;
            }
            System.out.println(count);
        }
    }
    public static boolean isP(int n) {
        int sum = 0;
        for(int i = 1; i * i <= n; i++) {
            if(n % i == 0) {
                int k = n / i;
                if(k == i) {
                    sum += i;
                } else {
                    sum += (i + k);
                }
            }
        }
        if(sum == 2 * n) {
            return true;
        } else {
            return false;
        }
    }
}

发表于 2021-10-31 22:30:55 回复(0)
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        while (scan.hasNext()) {
            int a = scan.nextInt();
            int count = 0;
            for (int i = 1; i <= a; i++) {
                int sum = 0;
                for (int j = 1; j <= Math.sqrt(i); j++) {
                    if (i % j == 0) {
                        sum += (j + i / j);
                    }
                }
                if (sum == i * 2) {
                    count += 1;
                }
            }
            System.out.println(count - 1);
        }
    }
}

发表于 2021-09-20 23:34:33 回复(0)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Consoletest1
{
    public class MainClass
    {
        public static void Main()
        {
            string a = Console.ReadLine();
            List<int> kk = new List<int>();
            int c = 0;
            int he = 0;
            int count = 0;
            while (a != null)
            {
                c = Convert.ToInt32(a);
                for (int j = 1; j <= c; j++)
                {
                    for (int i = 1; i < j ; i++)
                    {
                        if (j % i == 0)
                        {
                            he += i;
                        }
                    }
                    if (he == j)
                    {
                        count++;
                    }
                    he = 0;
                }
                kk.Add(count);
                count = 0;
                a = Console.ReadLine();
            }
            foreach (int s in kk)
            {
                Console.WriteLine("{0}",s);
            }
            Console.ReadKey();
        }
    }
}
发表于 2021-09-08 17:28:49 回复(0)
while True:
    try:
        n = int(input())
        a = {}
        for i in range(1, n+1):
            a[i] = 1
        for i in range(2, int(n**0.5)+1):
            a[i*i] = a[i*i] + i
            for j in range(i+1, n//i+1):
                a[i*j] = a[i*j] + i + j
        sum = 0
        for i in range(2, n+1):
            if a[i] == i:
                sum += 1

        print(sum)

    except:
        break


发表于 2021-06-23 22:54:52 回复(0)
import java.util.Scanner;
public class Main {
        public static void main(String[] args){
            Scanner sc=new Scanner(System.in);
            while(sc.hasNext()){
                int n=sc.nextInt();
                int count=0;
                for(int i=1;i<=n;i++)
                    if(sums(i)==i)count++;
                System.out.println(count);
            }
        }
    public static int sums(int n){
        int res=0;
        for(int i=1;i<=n/2;i++){                    //此处开始想用Math.sqrt以节省时间,后来明白,那样做时间节省,结果错误,用n/2刚刚好
            if(n%i==0)res+=i;
        }
        return res;
    }
}
编辑于 2021-06-15 11:08:41 回复(0)
def is_perfectNum(num):
    L = []
    for i in range(1,num):
        if num % i == 0:
            L.append(i)
    if sum(L) == num:
        return True
    return False

while True:
    try:
        n = int(input().strip())
        if 0 < n <= 500000:
            count_perfectNum = 0
            for i in range(1, n+1):
                if is_perfectNum(i):
                    count_perfectNum += 1
            print(count_perfectNum)
    except:
        break

方法一(上述方法):直接给出判断完全数的方法,然后以遍历的方式,一个一个地找完全数
方法二:利用欧拉公式——如果i是质数,2^i-1也是质数,那么(2^i-1)*2^(i-1)就是完全数
def checkprime(num):
    if num == 1:
        return False
    list1 = []
    for i in range(2, num):
        if num % i == 0:
            list1.append(i)
    if not list1:
        return True
    else:
        return False

while True:
    try:
        n = int(input())
        res = []
        for i in range(1, n+1):
            if (2**i-1)*2**(i-1) > n:
                break
            elif checkprime(i) and checkprime(2**i-1):
                res.append((2**i-1)*2**(i-1))
        print(len(res))
    except:
        break


编辑于 2020-12-06 17:46:11 回复(0)
这个题貌似没太多简便算法,首先想到的就是遍历,而且很自然想到遍历区间是每个数的开方
def perfectnum(n):
    if n <= 5: return 0
    cnt = 0
    for i in range(6, n+1):
        add = 1
        for j in range(2, int(i**0.5)+1):
            if i%j == 0:
                add = add + j + i//j
        if add == i: cnt += 1
    return cnt
while True:
    try:
        n = int(input())
        print(perfectnum(n))
    except:
        break


发表于 2020-08-26 15:53:52 回复(0)
def is_perfect(num):
    yinzi = []
    for i in range(1,num//2+1):
        if num%i==0:
            yinzi.append(i)
    if sum(yinzi)==num:
        return True
    else:
        return False

while True:
    try:
        n = int(input())
        if n<=0 or n>500000:
            print(-1)
            break
        else:
            count_ = 0
            for num in range(2,n+1):
                if is_perfect(num):
                    count_ += 1
            print(count_)
    except:
        break

编辑于 2020-07-29 21:18:15 回复(0)
#900ms,还行吧,简单易懂
def pn(n):
    if n < 0&nbs***bsp;n > 500000:
        return -1
    else:
        num = []
        for i in range(1,int(n/2)+1):
            if n % i == 0:
                num.append(i)
        if sum(num) == n:
            return n
        else:
            return -1
while True:
    try:
        n = int(input())
        count = 0
        for i in range(1,n+1):
            if pn(i) == i:
                count += 1
        print(count)
    except:
        break

发表于 2020-07-25 18:40:59 回复(1)
#include <iostream>

using namespace std;
//把每一个数n 去一次对1-n/2个数取余,进行判断即可
int main()
{
    int n;
    while(cin>>n)
    {
        int res = 0;
        for(int i = 1;i<=n;i++)
        {
            int tmp = 0;
            for(int j = 1;j<=i/2;j++)
            {
                if(i % j == 0)    tmp+=j;
            }
            if(tmp == i)  res++;
        }
        cout<<res<<endl;
    }

    return 0;
}

发表于 2020-07-13 10:55:18 回复(0)
#include<iostream>
(720)#include<math.h> 
using namespace std;
bool iscount(int n){
	int sum=0;
		for(int i=1;i<n;i++){
			if(n%i==0){
				sum=sum+i;
			}
		}
		if(sum==n){
			return true;
		}else{
			return false;
		}
	

}
int main(){
	int n;
	while(cin>>n){
		int temp=0;
		for(int i=1;i<=n;i++){
			if(iscount(i)){
				temp++;
			}
		}
		cout<<temp<<endl;
	}
}

发表于 2020-04-04 10:06:35 回复(0)
from functools import reduce
while True:
    try:
        n = int(input())
        result = []
        count = 0
        if n > 1:
            for i in range(1,n+1):
                add_num = []
                for j in range(1,i+1):
                    if i % j == 0:
                        add_num.append(j)
                add_num.remove(i)
                result.append(add_num)      
        
            for i in range(2,n):
                if reduce(lambda x,y : x+y , result[i-1]) == i:     
                     count +=1
            print(count)
        else:
            print(0)
    except:
        break
1,将1到n之间的数字的因子都放进result列表中,result[0]代表的是 1的因子,result[n-1]代表n的因子
2,将result里面的数字一一计算,是否完美数字。result[n-1]代表n的因子
算法自认为没问题,但是超时了~~
case  80%
发表于 2020-03-27 22:32:01 回复(0)

c++做法

用的方法可能比较基础,虽然好懂,但是可能有点复杂?大神的算法都太难懂了……
#include <iostream>
#include <vector>
using namespace std;
int Fill_Array(vector<int> &res, int startV, int n)
{
    
    for(int i=startV; i<=n; ++i)
    {
        int sum_yueshu = 0;
        for(int j=1; j<i; ++j)
        {
            if(i%j==0)
                sum_yueshu += j;
        }
        if(sum_yueshu == i)
            res.push_back(i);
    }
    return res.size();
}
int main()
{
    int input_num;
    //把完全数扔进去
    vector<int> res;
    //记录找过的最大的数,这样比这个数小的可以直接去完全数数组里找
    int Num_Max = 28;
    //第一个应该是28,写进去
    res.push_back(28);
    while(cin >> input_num)
    {
        if(input_num <= 28)
        {
            if(input_num == 28)
                cout << 1 << endl;
            else
                cout << 0 << endl;
        }
        //当输入的大于这个数时去试着
        else if(Num_Max < input_num)
        {
            int output_num = Fill_Array(res, Num_Max, input_num);
            Num_Max = input_num;
            cout << output_num << endl;
        }
        //当输入的不超过之前查询过的数,则直接去查数量就好
        else
        {
            int output_num = 0;
            for(int i=0; i<res.size(); ++i)
            {
                if(res[i] <= input_num)
                    output_num++;
                else
                    break;
            }
            cout << output_num << endl;
        }
    }
}


发表于 2020-02-05 12:06:18 回复(2)

问题信息

难度:
621条回答 31726浏览

热门推荐

通过挑战的用户

查看代码
完全数计算