嘿,各位,今天咱来玩点有意思的编程小挑战 —— 输入 n 个整数求和,再判断总和是不是质数。别慌!
一、需求拆解
咱得实现这么个功能:
第一步,用户输入一个整数 n ,代表要输入的整数个数
第二步,接着输入 n 个整数,然后把它们加起来,得到总和 sum
第三步,判断这个 sum 是不是质数。要是质数,输出 “prime” ;不是的话,输出 “not prime”
质数嘛,就是那种除了 1 和自己,没别的数能整除它的数(因数),像 2、3、5、7 这些。相信读了小学,就知道!
二、代码实现
程序开始跑!
#include <iostream>
using namespace std;
#include <iostream>
using namespace std;
int main() {
// 定义变量,n 是个数,a 用来存每次输入的数,sum 存总和
int n, a, sum = 0;
// 输入 n 的值
cin >> n;
// 第一个 for 循环:输入 n 个数并求和
for (int i = 1; i <= n; ++i) {
cin >> a;
sum += a;
}
// 定义变量 num,用来标记是不是质数,初始设为 0
int num = 0;
// 第二个 for 循环:判断 sum 是不是质数
for (int i = 2; i <= sum / 2; ++i) {
if (sum % i == 0) {
num++;
cout << "not prime" << endl;
break;
}
}
// 根据 num 的值判断并输出结果
if (num == 0 && sum > 1) {
cout << "prime" << endl;
}
return 0;
}
- 变量定义:
int n, a, sum = 0; 这里 n 是要输入的整数个数, a 用来临时存每次输入的整数, sum 一开始要给初始值 0,等着把输入的数加起来。
- 第一个 for 循环:
for (int i = 1; i <= n; ++i) 会循环 n 次,每次把用户输入的数 a 加到 sum 里,就像把一堆数挨个往“总和口袋”里塞。
- 第二个 for 循环:
for (int i = 2; i <= sum / 2; ++i) 是用来判断 sum 是不是质数的。从 2 开始,到 sum / 2 结束(因为大于 sum / 2 的数除了 sum 自己,不可能整除 sum 啦 )。要是在循环里找到能整除 sum 的数,就把 num 加 1,然后输出 “not prime” 并跳出循环,说明这数不是质数。
- 最后的判断:
if (num == 0 && sum > 1) ,如果 num 还是 0,而且 sum 大于 1(因为 1 不是质数哟 ),那就说明 sum 是质数,输出 “prime” 。
三、代码测试
咱拿例子试试:
- 样例 1:输入 4 1 2 1 3 。 n 是 4,然后输入 1、2、1、3 ,总和 sum = 1 + 2 + 1 + 3 = 7 。判断 7 是不是质数,从 2 开始试除,到 3(7/2 是 3.5,所以循环到 3 ),都没法整除,所以输出 “prime” ,yes~
- 样例 2:输入 5 1 4 5 2 2 。 n 是 5,输入的数加起来 sum = 1 + 4 + 5 + 2 + 2 = 14 。判断的时候,当 i = 2 , 14 % 2 == 0 ,所以 num 变成 1 ,输出 “not prime” ,ok~
四、总结:咱做了啥
通过这几行代码,咱就实现了“输入 n 个数求和并判断总和是否为质数”的功能。代码里用了两个 for 循环,一个负责求和,一个负责判断质数,变量 num 当“侦察兵”,帮咱标记是不是质数。
其实编程就像解谜,一步步把需求拆开来,再用代码的“工具”一个个解决,圆满完成!
秘密加餐:质数判断的其他简单写法
写法 1:最基础的暴力枚举(逐一遍历判断)
// 功能:判断一个数是否为质数(基础暴力版)
bool isPrime(int num) {
// 小于 2 的数直接不是质数(质数定义要求大于1)
if (num < 2)
return false;
// 从 2 遍历到 num-1,检查是否能整除
for (int i = 2; i < num; i++) {
if (num % i == 0) {
return false; // 能整除,不是质数
}
}
return true; // 遍历完都没整除,是质数
}
- 先处理 num < 2 的情况(质数必须大于 1),直接返回 false 。
- 用 for 循环从 2 遍历到 num-1 ,只要发现 num 能被其中某个数整除( num % i == 0 ),就说明不是质数,返回 false 。
- 遍历结束都没找到因数,说明是质数,返回 true 。
缺点:效率低(比如判断 1000000007 这类大质数时,要循环近 1 亿次),但逻辑 超级直观
写法 2:优化遍历范围(减少循环次数)
// 功能:判断一个数是否为质数(优化遍历版)
bool isPrime(int num) {
if (num < 2) return false;
// 只需要遍历到 sqrt(num)!
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
- 核心优化点:因数是成对出现的(比如 12 = 2×6 = 3×4 ),所以只要检查到 sqrt(num) 就够了。如果 num 有大于 sqrt(num) 的因数,那必然对应一个小于 sqrt(num) 的因数。
- 用 i * i <= num 代替 i < num ,循环次数大幅减少(比如判断 100 ,原来要循环 98 次,现在只需循环到 10 )。
- 逻辑和写法 1 一致,实际用得最多 。
写法 3:极致简化(一行代码逻辑,适合理解后拓展)
// 功能:判断一个数是否为质数(极简逻辑版)
bool isPrime(int num) {
// 结合优化遍历 + 逻辑压缩
for (int i = 2; i * i <= num && num > 1; i++)
if (num % i == 0) return false;
return num > 1;
}
- 把 num < 2 的判断藏进循环条件和返回值里:
- 循环条件 i * i <= num && num > 1 :如果 num <= 1 ,循环直接不执行。
- 最后返回 num > 1 :如果循环没执行( num <=1 ),返回 false ;如果循环执行完没找到因数,返回 true (因为质数定义是大于 1 )。
- 优点:代码极短,适合理解后挑战“极简写法”;缺点:可读性略降
怎么用这些函数?(完整示例)
把上面的 isPrime 函数放到你的代码里,就能替代原来的质数判断逻辑。比如结合你最初的“求和后判断质数”需求,完整代码可以这样写:
#include <iostream>
using namespace std;
// 复制上面任意一个 isPrime 函数到这里
bool isPrime(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() {
int n, a, sum = 0;
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a;
sum += a;
}
// 直接调用 isPrime 函数判断
if (isPrime(sum)) {
cout << "prime" << endl;
} else {
cout << "not prime" << endl;
}
return 0;
}
这些写法覆盖了“从理解原理”到“实际应用”的过程,一步步学,质数判断再也不会迷糊啦~
文章有点长,感谢看完,点个赞支持下呗!
有不足请大佬指正!