完数 VS 盈数 C++

描述

题目描述
一个数如果恰好等于它的各因子(该数本身除外)子和,如:6=3+2+1。则称其为“完数”;若因子之和大于该数,则称其为“盈数”。 求出2到60之间所有“完数”和“盈数”。

输入描述:
题目没有任何输入。
输出描述:
输出2到60之间所有“完数”和“盈数”,并以如下形式输出:
E: e1 e2 e3 ……(ei为完数)
G: g1 g2 g3 ……(gi为盈数)
其中两个数之间要有空格,行尾不加空格。

分析

数很小,暴力方法做就可以,注意因子的话只找到sqrt还不行,会漏掉,得找到n-1才行

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int E[70], G[70];
int main()
{
    int te = 0, tg = 0;
    for (int i = 2; i <= 60; i++)
    {
        int sum = 0;
        for (int j = 1; j <i; j++)
        {
            if (i%j == 0)sum += j;
        }
        if (sum == i)E[te++] = i;
        else if (sum > i)G[tg++] = i;
    }
    printf("E: ");
    for (int i = 0; i < te - 1; i++)
        printf("%d ", E[i]);
    printf("%d\n", E[te - 1]);
    printf("G: ");
    for (int i = 0; i < tg - 1; i++)
        printf("%d ",G[i]);
    printf("%d\n", G[tg - 1]);
}

以下是几种使用C++语言寻找完数的代码和实现方法: ### 常规解法 该方法通过遍历范围内的每个,找出其所有因子并求和,若因子和等于该本身,则该完数。 ```cpp #include <iostream> using namespace std; int main(void) { int i, j, k, sum; cout << "请输入所求整范围上限:" << endl; cin >> k; // 键入范围上限 for (i = 2; i <= k; i++) { sum = 0; // 保证每一次循环sum都为0 for (j = 1; j < i; j++) { if (i % j == 0) // 判断j是否为i的因子 sum += j; } if (sum == i) // 判断因子和与i相等 cout << "完数为:" << i << endl; } return 0; } ``` 此代码的实现思路是先让用户输入一个范围上限`k`,然后从2开始遍历到`k`,对于每个`i`,计算其所有小于`i`的因子之和`sum`,若`sum`等于`i`,则`i`为完数并输出 [^1]。 ### 函封装解法 将判断一个是否为完数的逻辑封装成函,提高代码的复用性。 ```cpp #include <iostream> using namespace std; /* 判断一个字是否为完数 */ bool determining_completion(int n) { int sum = 0; for (int i = 1; i < n; i++) { if (n % i == 0) { sum += i; } } if (sum == n) return true; else return false; } int main() { // 读入范围的上下限 int a = 0, b = 0; cout << "请输入需要判断的范围 ( a-b ) :\n"; cout << "a = "; cin >> a; cout << "\nb = "; cin >> b; cout << "\nFrom " << a << " to " << b << " 完数有:\n\n"; int num = 0; // 循环判断范围内的每个字,如果为完数,输出 for (int i = a; i < b + 1; i++) { if (determining_completion(i)) { // 记录完数的个 num++; // 输出完数 cout << i << " "; } } cout << "\n\n共计 " << num << " 个\n"; return 0; } ``` 此代码中,`determining_completion`函用于判断一个是否为完数,在`main`函中,用户输入一个范围`[a, b]`,然后遍历该范围内的每个,调用`determining_completion`函进行判断,若为完数则输出并记录个 [^2]。 ### 优化遍历范围解法 在寻找因子时,只需要遍历到`i/2`,减少不必要的计算。 ```cpp #include <iostream> using namespace std; int main() { int m, n; int i, j; int s, p, flag = 0; cout << "请输入范围的上下限(用空格分隔):"; cin >> m >> n; // 遍历m到n,检查这个范围内的每一个是否为完数 for (i = m; i <= n; i++) { s = 0; // 在每次循环开始前,将s重置为0 // 遍历1到i/2,用于找出字i的所有因子 for (j = 1; j <= i / 2; j++) { // 如果j是i的因子(即i能被j整除) if (i % j == 0) // 将j加到s中,即把j作为字i的一个正因子 s += j; } // 如果s等于i(i的所有因子的和等于i本身) if (s == i) { flag = 1; // 设置flag为1,表示找到了一个完数 cout << i << " = "; p = 0; // 将p重置为0,用于存储某字的累加和 for (j = 1; j <= i / 2; j++) { if (i % j == 0) { p += j; // 将j加到p中(累加) if (p != i) // 如果p不等于i(即不是最后一个i本身) cout << j << " + "; else // 如果p等于i(即这是最后一个) cout << j << endl; } } } } // 如果在整个过程中flag都保持为0(即没有找到任何完数),那么输出None if (flag == 0) cout << "None" << endl; return 0; } ``` 此代码中,在寻找因子时,将内层循环的范围从`1`到`i-1`优化为`1`到`i/2`,减少了不必要的计算。用户输入范围`[m, n]`,遍历该范围内的每个,找出其所有小于等于`i/2`的因子之和`s`,若`s`等于`i`,则`i`为完数并按格式输出 [^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值