「经典数字题」集合 | C/C++

- 第 140 篇 -
Date: 2025 - 11 - 02
Author: 郑龙浩(仟墨)

Date: 2025-11-02

Author: 郑龙浩

「经典数字题」集合 | C/C++

1. 水仙花数(Narcissistic Number)

解释:一个3位数,其各位数字的3次方之和等于该数本身

其实就是3位的阿姆斯特朗数:n位数的每个数字的n次幂之和等于该数本身(水仙花数是3位阿姆斯特朗数)

示例

  • 153 = 1³ + 5³ + 3³ = 1 + 125 + 27 = 153
  • 370 = 3³ + 7³ + 0³ = 27 + 343 + 0 = 370
  • 要求:判断水仙花数
cpp 复制代码
// 1. 水仙花数
// 一个n位数,其各位数字的n次方之和等于该数本身
#include "bits/stdc++.h"
using namespace std;
// 纯数字版 (倒叙存储新数字)
bool fun1(long long n) {
    long long sum = 0, n2 = n, len = 0;
    while (n2) {
        len++;
        n2 /= 10; // 抹掉最后一位
    }
    n2 = n;
    while (n2) {
        sum += pow(n2 % 10, len);
        n2 /= 10;
    }
    return sum == n;
}
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cout << fun1(153) << ' ' << fun1(370) << ' ' << fun1(12);
    return 0;
}

2. 回文数(Palindrome Number)

解释:正读和反读都一样的数字

示例:121, 12321, 3443

要求:判断一个数是否为回文数

cpp 复制代码
// 2. 回文数(Palindrome Number)
// 正读和反读都一样的数字
#include "bits/stdc++.h"
using namespace std;
// 纯数字版 (倒叙存储新数字)
bool fun1(int n) {
    int n1 = n, n2 = 0; // n1保护n,n2存储倒序n
    while (n) {
        n2 = n2 * 10 + n % 10; // 将n低位存储到n2倒序数字中
        n /= 10; // 保留高位
    }
    return n1 == n2; // 如果n1 == n2 就返回true,否则false
}
// 数字版 (双指针法)
bool fun2(vector <int> &arr) {
    for (int i = 0, j = arr.size()-1; i < j; i++, j--) {
        if (arr[i] != arr[j]) return false;
    }
    return true;
}
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int num = 12321, num2 = 12345;
    vector <int> arr = {1, 2, 3, 4, 5, 4, 3, 2, 1};
    vector <int> arr2 = {1, 1, 3, 4, 5, 4, 3, 2, 1};
    cout << fun1(num) << fun1(num2) << '\n';
    cout << fun2(arr) << fun2(arr2);
    return 0;
}

3. 偶数/奇数判断

解释

  • 偶数:能被2整除的数(0, 2, 4, 6, 8...)
  • 奇数:不能被2整除的数(1, 3, 5, 7, 9...)
  • 要求:判断数字的奇偶性
cpp 复制代码
#include "bits/stdc++.h"
using namespace std;
bool fun(int num) {
    return num % 2; // 偶数返回0,奇数返回1
}
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int num;
    cin >> num;
    cout << (fun(num) ? "奇数" : "偶数");
    return 0;
}

4. 素数(质数)

解释:大于1的自然数,除了1和它本身以外不再有其他因数

示例:2, 3, 5, 7, 11, 13...

要求:判断一个数是否为素数

cpp 复制代码
// 4_素数(质数)
#include "bits/stdc++.h"
using namespace std;
// 普通版
bool fun1(int num) {
    if (num < 2) return false;  // 特判
    for (int i = 2; i < num; i++) {
        if (num % i == 0) return false;
    }
    return true;
}
// i * i <= num优化版
// 举例:判断 36 是否为素数:
// 36 的因数对:(1,36), (2,18), (3,12), (4,9), (6,6)
// 平方根:√36 = 6
// 我们只需要检查到 6 即可,因为如果 36 有大于 6 的因数,那么它必然有对应的小于 6 的因数
bool fun2(int num) {
    if (num < 2) return false;  // 特判
    for (int i = 2; i * i < num; i++) {
        if (num % i == 0) return false;
    }
    return true;
}
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int num;
    cin >> num;
    cout << (fun1(num) ? "是素数":"不是素数");
    cout << (fun2(num) ? "是素数":"不是素数");
    return 0;
}

5. 完数(完全数)

解释:一个数恰好等于它的真因子(除了自身以外的约数)之和

示例:6 = 1 + 2 + 3,28 = 1 + 2 + 4 + 7 + 14

要求:判断是否是完全数

cpp 复制代码
// 5. 完数(完全数)
// 思路:
// 1 循环遍历 1 ~ num/2的所有整数(遍历变量i)
// 2 累加所有因子:对于每个 i,检查是否能被 num 整除(即 num % i == 0)如果能整除,则将 i 累加到 sum 中
// 3 遍历结束后,sum == num 则是完全数,sum != num 不是完全数
#include "bits/stdc++.h"
using namespace std;
bool fun(int num) {
    int sum = 0;
    for (int i = 1; i <= num/2; i++) {
        if (num % i == 0) sum += i; // 将所有因子累加
    }
    return sum == num; // 如果累加 == num,就是完全数
}

int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int num;
    cin >> num;
    cout << (fun(num) ? "是完全数":"不是完全数");
    return 0;
}

6. 斐波那契数列

解释:每个数字是前两个数字之和的数列

序列:0, 1, 1, 2, 3, 5, 8, 13, 21...

要求:输出斐波那契数列的第n项

cpp 复制代码
 // 5. 完数(完全数)
// 思路:
// 1 循环遍历 1 ~ num/2的所有整数(遍历变量i)
// 2 累加所有因子:对于每个 i,检查是否能被 num 整除(即 num % i == 0)如果能整除,则将 i 累加到 sum 中
// 3 遍历结束后,sum == num 则是完全数,sum != num 不是完全数
#include "bits/stdc++.h"
using namespace std;
// 变循环边输出:非数组 + 非递归
int fun1(int num) {
    int a, b, c;
    a = b = 1; // 设置初值
    for (int i = 3; i <= num; i++) {
        c = a + b; // 下一项
        a = b;
        b = c;
    }
    return c;
}
// 数组版
int fun2(int num) {
    vector <int> nums(num);
    nums[0] = nums[1] = 1;
    for (int i = 2; i < num; i++) {
        nums[i] = nums[i - 1] + nums[i - 2];
    }
    cout << nums[num - 1];
}
// 递归版(最简洁)
int fun3(int n) {
    if (n <= 2) // 如果是第1项或第2项,就是1
        return 1;
    return fun3(n - 1) + fun3(n - 2);
}
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int num;
    cin >> num;
    cout << fun1(num)<< ' ';
    cout << fun2(num)<< ' ';
    cout << fun3(num)<< ' ';
    return 0;
}

7. 阿姆斯特朗数

解释:n位数的每个数字的n次幂之和等于该数本身(水仙花数是3位阿姆斯特朗数)

示例:1634 = 1⁴ + 6⁴ + 3⁴ + 4⁴ = 1 + 1296 + 81 + 256 = 1634

要求:找出指定位数的阿姆斯特朗数

cpp 复制代码
// 7.阿姆斯特朗数
// 一个n位数,其各位数字的n次方之和等于该数本身
#include "bits/stdc++.h"
using namespace std;
// 纯数字版 (倒叙存储新数字)
bool fun1(long long n) {
    long long sum = 0, n2 = n, len = 0;
    // 计算数字长度
    while (n2) {
        len++;
        n2 /= 10; // 抹掉最后一位
    }
    n2 = n; // 重置
    // 计算倒叙数字
    while (n2) {
        sum += pow(n2 % 10, len);
        n2 /= 10;
    }
    // 如果倒序数字和正序数字一样,就是阿姆斯特朗数
    return sum == n;
}
// 数组版(双指针)
bool fun2(vector <int> &nums) {
    int i = 0, j = nums.size();
    while (i < j) {
        if (nums[i] != nums[j]) return false;
    }
    return true;
}
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cout << fun1(153) << ' ' << fun1(370) << ' ' << fun1(12);
    cout << '\n';
    cout << fun1(153) << ' ' << fun1(370) << ' ' << fun1(12);
    return 0;
}

8.最大公约数(GCD)9.最小公倍数(LCM)

  • 最大公约数

解释:两个或多个整数共有约数中最大的一个

示例:gcd(12, 18) = 6

要求:计算两个数的最大公约数

  • 最小公倍数

解释:两个或多个整数公有的倍数中最小的一个

示例:lcm(12, 18) = 36

要求:计算两个数的最小公倍数

cpp 复制代码
// 8.最大公约数(GCD)9.最小公倍数(LCM)
// 
#include <iostream>
using namespace std;

// 方法1:辗转相除法
int fun1(int a, int b) {
    while (b != 0) {
        int t = b;
        b = a % b;
        a = t;
    }
    return a;
}
// 方法2:循环试除法
// 从两者最小的数字开始往下找两个数字相同的因子
int fun2(int a, int b) {
    for (int i = min(a, b); i >= 1; i--) {
        if (a % i == 0 && b % i == 0) {
            return i;
        }
    }
    return 1;
}

// 方法3:更相减损术
// 思路:两个数的最大公约数,等于较大数减较小数的差与较小数的最大公约数
int fun3(int a, int b) {
    while (a != b) {
        if (a > b) a = a - b;
        else b = b - a;
    }
    return a;
}

// 最小公倍数(纯套公式)
int fun4(int a, int b) {
    return a / fun1(a, b) * b;
}

int main() {
    int a, b;
    cout << "输入两个数: ";
    cin >> a >> b;
    
    cout << "最大公约数: " << fun1(a, b) << ' ' << fun2(a, b) << ' ' << fun3(a, b) << '\n';
    cout << "最小公倍数: " << fun4(a, b);
    return 0;
}

10. 阶乘计算

解释:一个正整数的阶乘是所有小于及等于该数的正整数的积

示例:5! = 5 × 4 × 3 × 2 × 1 = 120

要求:计算一个数的阶乘

cpp 复制代码
// 10_阶乘计算
// 一个正整数的阶乘是所有小于及等于该数的正整数的积
// Date: 2025年10月31日 Author: 郑龙浩
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
// 方法1: 循环累乘
ll fun1(ll n) {
    ll ans = 1;
    for (int i = 2; i <= n; i++) {
        ans *= i;
    }
    return ans;
}
// 方法2:递归
ll fun2(ll n) {
    if (n == 1) return 1;
    return fun2(n - 1) * n;
}
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cout << fun1(5) << '\n' << fun2(5);
    return 0;
}

11. 数字反转

解释:将一个整数的数字顺序颠倒

示例:12345 → 54321

要求:实现数字反转功能

cpp 复制代码
// 10_阶乘计算
// 一个正整数的阶乘是所有小于及等于该数的正整数的积
// Date: 2025年10月31日 Author: 郑龙浩
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
// 方法1: 整数数字反转
ll fun1(ll n) {
    ll n2 = 0;
    while (n) {
        n2 = n2 * 10 + n % 10;
        n /= 10;
    }
    return n2;
}
// 方法2:数组
void fun2(vector <int> &nums) {
    for (int i = 0, j = nums.size() - 1; i < j; i++, j--) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cout << fun1(12345) << '\n';
    vector <int> nums = {1, 2, 3, 4, 5};
    fun2(nums);
    for (int i : nums) cout << i;
    return 0;
}

12. 数字各位数之和

解释:计算一个整数各位数字相加的总和

示例:12345 → 1+2+3+4+5 = 15

要求:计算任意整数的各位和

cpp 复制代码
// 10_阶乘计算
// 一个正整数的阶乘是所有小于及等于该数的正整数的积
// Date: 2025年10月31日 Author: 郑龙浩
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    ll num, sum = 0;
    cin >> num;
    while (num) {
        sum += num % 10;
        num /= 10;
    }
    cout << sum;
    return 0;
}

13. 快乐数(Happy Number)

解释 :经过特定运算最终会变为1的数字

特定运算:重复计算各位数字的平方和,最终会变为1的数字(如果最终是循环,就不是快乐数)

示例:19 → 1²+9²=82 → 8²+2²=68 → 6²+8²=100 → 1²+0²+0²=1

要求:判断一个数是否为快乐数

cpp 复制代码
// 13. 快乐数
// 重复计算各位数字的平方和,直到结果为1或进入循环
// 19 →  1²+9²=82 → 8²+2²=68 → 6²+8²=100 → 1²+0²+0²=1
// Date: 2025年10月31日 Author: 郑龙浩
// 方法:使用哈希表记录已经计算过的数字
// 循环条件:数字不是1 && 这个数字没计算过(没见过)
// 循环内容:不断重复计算各位数字的平方和
// num == 1 证明最终变为了1,就是快乐数
// num != 1 证明最终陷入循环,就不是快乐数
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
unordered_set<int> seen;
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int num;
    cin >> num;
    // 数字不是1 && 这个数字没计算过(没见过)
    while (num != 1 && seen.find(num) == seen.end()) {
        seen.insert(num);
        int n = num;
        num = 0;
        // 计算当前数字的各位的平方和
        while (n) {
            num += (n % 10) * (n % 10);
            n /= 10;
        }
    }
    cout << (num == 1 ? "是快乐数" : "不是快乐数");
    return 0;
}

14. 强数(Strong Number)

解释:一个数等于其各位数字的阶乘之和

示例:145 = 1! + 4! + 5! = 1 + 24 + 120 = 145

要求:判断一个数是否为强数

cpp 复制代码
// 13. 快乐数
// 一个数等于其各位数字的阶乘之和
// 145 = 1! + 4! + 5! = 1 + 24 + 120 = 145
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
unordered_set<int> seen;
int  fact(int num) {
    if (num == 1) return 1;
    return fact(num - 1) * num;
}
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int n, num, sum = 0;
    cin >> n;
    num = n;
    while (num) {
        sum += fact(num % 10);
        num /= 10;
    }
    cout << (n == sum ? "是强数" : "不是强数");
    return 0;
}

15. 质因数分解

解释:将一个合数分解为质因数的乘积

质因数:既是质数又是某个数的因数(质数 + 因数)

示例:60 = 2 × 2 × 3 × 5

要求:对给定的数进行质因数分解

质因数分解时,需要判断找到的因子是否为质数吗?

**不需要!**记住这个特性就行:

  • 从2开始从小到大试除
  • 第一个能整除的因子一定是质数
  • 后续找到的能整除的因子也一定是质数

注意(一句话总结吧):从小到大试除,找到的因子自动就是质因数,不用额外判断

cpp 复制代码
// 15_质因数分解
// Date: 2025年10月31日 Author: 郑龙浩
// 将一个合数分解为质因数的乘积
// 60 = 2 × 2 × 3 × 5
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int num;
    cin >> num;
    cout << num << "= ";
    bool first = true; // 标记是否是第一个质因数,如果是第一个质因数则不打印*(乘号)如果不是第一个质因数就打印*(我的*是在输出质因数之前输出的)
    // 2 ~ num 试除所有可能的数
    for (int i = 2; i <= num; i++) {
        // 只要i可以除得开,就证明是最小质因数,就可以一直用,直到除不开,才换到下一个
        while (num % i == 0) {
            if (first != true) cout << " * ";// 输出*
            cout << i; // 输出当前的最小质因数
            num /= i; // 输出这个质因数后,就换到被质因数除后的数字
            first = false;
        }
    }
    return 0;
}                       

16. 二进制转换

解释:将十进制数转换为二进制表示

示例:10 → 1010, 15 → 1111

计算方法

cpp 复制代码
10 ÷ 2 = 5 ... 余0  (最低位)
5 ÷ 2 = 2 ... 余1
2 ÷ 2 = 1 ... 余0
1 ÷ 2 = 0 ... 余1  (最高位)
从下往上读:1010
cpp 复制代码
// 15_十进制转二进制
// Date: 2025年10月31日 Author: 郑龙浩
// 将一个合数分解为质因数的乘积
// 60 = 2 × 2 × 3 × 5
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int num;
    cin >> num;
    vector <bool> arr;
    while (num) {
        arr.push_back(num % 2); // 将新的二进制数插入至末尾
        num /= 2; // 更新num为除以2后的结果
    }
    for (int i = arr.size()-1; i >= 0; i--) cout << arr[i];
    return 0;
}                       

17. 数字统计

解释:统计数字中各个数字出现的次数

示例:112233中,1出现2次,2出现2次,3出现2次

要求:统计数字中0-9每个数字的出现次数

cpp 复制代码
// 17. 数字统计
// Date: 2025年10月31日 Author: 郑龙浩
// 思路:利用数组存储0~9的数字的出现次数
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    vector <int> nums(10);
    ll num; cin >> num;
    while (num) {
        nums[num % 10]++;
        num /= 10; // 去除最后一位
    }
    for (int i = 0; i < 10; i++) printf("%d的数量是%d\n", i, nums[i]);
    return 0;
}

18. 丑数(Ugly Number)(LeetCode 263题)

解释:只包含质因子2、3、5的正整数

示例:1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15...

cpp 复制代码
// 18. 数字排列组合
// Date: 2025年11月1日 Author: 郑龙浩

// **示例**:数字1,2,3的排列:123, 132, 213, 231, 312, 321
// 纯套循环
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int n; cin >> n;
    if (n <= 0) {cout << "不是丑数"; return 0;} // 边界条件处理:0和负数不是丑数
    // 如果一个数只包含2、3、5这三种质因子,那么通过不断除以2、3、5,最终会得到1
    while (n % 2 == 0) n /= 2;
    while (n % 3 == 0) n /= 3;
    while (n % 5 == 0) n /= 5;
    if (n == 1) cout << "是丑数";
    else cout << "非丑数";
    return 0;
}
相关推荐
fpcc7 小时前
C++编程实践——eventFD
linux·c++
Skrrapper7 小时前
【STL】set、multiset、unordered_set、unordered_multiset 的区别
c++·算法·哈希算法
SunnyKriSmile7 小时前
函数递归求最大值
c语言·算法·函数递归
lkbhua莱克瓦248 小时前
Java练习——正则表达式2
java·开发语言·笔记·正则表达式·github·学习方法
冷崖8 小时前
QML-Model-View
javascript·c++
degen_8 小时前
DXE流程
c语言·笔记·bios
懒羊羊不懒@8 小时前
JavaSe—List集合系列
java·开发语言·数据结构·人工智能·windows
峥无8 小时前
《从适配器本质到面试题:一文掌握 C++ 栈、队列与优先级队列核心》
开发语言·c++·queue·stack
七夜zippoe8 小时前
仓颉FFI实战:C/C++互操作与性能优化
c语言·c++·性能优化