C++ 循环结构练习题目集
题目1:分离数位
题目描述
输入一个正整数,将其每一位数字按从低位到高位的顺序输出,数字之间用空格分隔。
输入样例
123
输出样例
3 2 1
数据范围
-
1 ≤ x ≤ 10^5
参考代码
#include <iostream>
using namespace std;
int main() {
int x;
cin >> x;
while (x > 0) {
cout << x % 10 << " ";
x = x / 10;
}
return 0;
}
解题思路
-
通过
x % 10获取最低位数字。 -
通过
x = x / 10去掉最低位,循环直到所有数位处理完毕。
知识点
-
循环结构、数位分离(取余和整除操作)。
题目2:含有k个3的数
题目描述
输入两个整数 m 和 k,判断 m 的十进制表示中是否恰好包含 k 个数字 3。
输入样例
333 3
输出样例
YES
数据范围
-
1 < m < 1e5
-
1 < k < 5
参考代码
#include <iostream>
using namespace std;
int main() {
int m, k, cnt = 0;
cin >> m >> k;
int tmp = m;
while (tmp > 0) {
if (tmp % 10 == 3) cnt++;
tmp /= 10;
}
cout << (cnt == k ? "YES" : "NO");
return 0;
}
解题思路
-
遍历每一位数字,统计 3 出现的次数。
-
比较统计结果与 k 是否相等。
知识点
-
循环结构、条件判断。
题目3:数字出现次数统计
题目描述
输入两个整数 n 和 x,统计从 1 到 n 的所有整数中,数字 x 出现的总次数。
输入样例
11 1
输出样例
4
数据范围
-
1 ≤ n ≤ 1e5
-
0 ≤ x ≤ 9
参考代码
#include <iostream>
using namespace std;
int main() {
int n, x, cnt = 0;
cin >> n >> x;
for (int i = 1; i <= n; i++) {
int tmp = i;
while (tmp > 0) {
if (tmp % 10 == x) cnt++;
tmp /= 10;
}
}
cout << cnt;
return 0;
}
解题思路
-
外层循环遍历 1 到 n 的所有数字。
-
内层循环分离每个数字的位数,统计 x 的出现次数。
知识点
-
双重循环、数位分离。
题目4:回文数判断
题目描述
输入一个整数,判断它是否为回文数(正读和倒读相同)。
输入样例
121
输出样例
是回文数
数据范围
-
1 ≤ x ≤ 1e9
参考代码
#include <iostream>
using namespace std;
int main() {
int x;
cin >> x;
int original = x, reversed = 0;
while (x > 0) {
reversed = reversed * 10 + x % 10;
x /= 10;
}
cout << (original == reversed ? "是回文数" : "不是回文数");
return 0;
}
解题思路
-
将原数字反转生成新数字。
-
比较原数字与反转后的数字是否相同。
知识点
-
数字反转、循环结构。
题目5:密码验证
题目描述
输入一个整数,若其逆序后的值等于 987,则输出“密码正确”,否则输出“密码错误”。
输入样例
789
输出样例
密码正确
数据范围
-
1 ≤ x ≤ 1e9
参考代码
#include <iostream>
using namespace std;
int main() {
int x;
cin >> x;
int reversed = 0, tmp = x;
while (tmp > 0) {
reversed = reversed * 10 + tmp % 10;
tmp /= 10;
}
cout << (reversed == 987 ? "密码正确" : "密码错误");
return 0;
}
解题思路
-
反转输入的数字。
-
检查反转后的结果是否为 987。
知识点
-
数字反转、条件判断。
题目6:闰年判断
题目描述
输入一个年份 a,判断它是否为闰年。闰年规则:能被 4 整除但不能被 100 整除,或能被 400 整除。
输入样例
输出样例
复制
YES
数据范围
-
1 ≤ a ≤ 3000
参考代码
#include <iostream>
using namespace std;
int main() {
int a;
cin >> a;
bool is_leap = (a % 4 == 0 && a % 100 != 0) || (a % 400 == 0);
cout << (is_leap ? "YES" : "NO");
return 0;
}
解题思路
-
直接根据闰年规则编写条件表达式。
知识点
-
条件运算符、逻辑表达式。
题目7:小鱼的游泳训练
题目描述
小鱼从周 x 开始,连续游泳 n 天。工作日(周一至周五)每天游 250 米,周末不游。计算总游泳距离。
输入样例
1 3
输出样例
750
数据范围
-
1 ≤ x ≤ 7
-
1 ≤ n ≤ 1e6
参考代码
#include <iostream>
using namespace std;
int main() {
int x, n, distance = 0;
cin >> x >> n;
for (int i = 0; i < n; i++) {
if (x != 6 && x != 7) distance += 250;
x = (x == 7) ? 1 : x + 1;
}
cout << distance;
return 0;
}
解题思路
-
循环处理每一天,累加工作日的游泳距离。
-
使用模运算处理星期的循环。
知识点
-
循环结构、星期计算、条件判断。
题目8:水仙花数判断
题目描述
判断一个三位数是否为水仙花数(各位数字立方和等于原数)。输出所有三位水仙花数。
输入样例
无输入
输出样例
153 370 371 407
数据范围
固定处理三位数(100 ≤ n ≤ 999)
参考代码
#include <iostream>
using namespace std;
int main() {
for(int n = 100; n < 1000; n++) {
int a = n/100, b = n/10%10, c = n%10;
if(n == a*a*a + b*b*b + c*c*c)
cout << n << " ";
}
return 0;
}
解题思路
-
遍历所有三位数
-
分离百位、十位、个位
-
验证立方和条件
知识点
-
数位分离、循环结构、幂运算
题目9:数列最大跨度
题目描述
输入一个正整数m和m个非负整数,输出数列最大值与最小值的差。
输入样例
5 8 3 6 2 5
输出样例
6
数据范围
-
1 ≤ m ≤ 1e5
-
0 ≤ 数值 ≤ 1000
参考代码
#include <iostream>
using namespace std;
int main() {
int m, num, zmax = 0, zmin = 1000;
cin >> m;
for(int i=0; i<m; i++) {
cin >> num;
if(num > zmax) zmax = num;
if(num < zmin) zmin = num;
}
cout << zmax - zmin;
return 0;
}
解题思路
-
初始化最大最小值
-
遍历输入时实时更新极值
知识点
-
极值算法、循环输入处理
题目10:偶数和计算
题目描述
输入正整数n,计算1到n之间所有偶数的和。
输入样例
6
输出样例
12
数据范围
-
1 ≤ n ≤ 1e6
参考代码
#include <iostream>
using namespace std;
int main() {
int n, sum = 0;
cin >> n;
for(int i=2; i<=n; i+=2)
sum += i;
cout << sum;
return 0;
}
解题思路
-
步长2遍历偶数
-
累加求和
知识点
-
循环步长控制、等差数列求和
题目11:四叶玫瑰数
题目描述
找出所有四叶玫瑰数(四位数的各位四次方之和等于自身)。
输入样例
无输入
输出样例
1634 8208 9474
数据范围
固定处理四位数(1000 ≤ n ≤ 9999)
参考代码
#include <iostream>
using namespace std;
int main() {
for(int i=1000; i<10000; i++) {
int a = i/1000, b = i/100%10, c = i/10%10, d = i%10;
if(i == a*a*a*a + b*b*b*b + c*c*c*c + d*d*d*d)
cout << i << " ";
}
return 0;
}
解题思路
-
遍历所有四位数
-
分离各位并验证四次方和
知识点
-
多位分离、幂运算优化
题目12:最长正常血压
题目描述
输入n个小时的血压记录,输出最长连续正常血压小时数(收缩压90-140且舒张压60-90)。
输入样例
复制
5 100 70 135 85 150 65 120 80 110 75
输出样例
3
数据范围
-
1 ≤ n ≤ 1e4
-
0 ≤ 血压值 ≤ 200
参考代码
#include <iostream>
using namespace std;
int main() {
int n, a, b, t=0, m=0;
cin >> n;
for(int i=0; i<n; i++) {
cin >> a >> b;
if(a>=90 && a<=140 && b>=60 && b<=90) {
t++;
if(t > m) m = t;
} else t = 0;
}
cout << m;
return 0;
}
解题思路
-
实时维护当前连续正常时长
-
遇到异常重置计时器
知识点
-
状态维持、极值更新
题目13:质数分解
题目描述
输入偶数n(n>2),找到两个质数使其和等于n且乘积最大。
输入样例
20
输出样例
91
数据范围
-
4 ≤ n ≤ 1e4
参考代码
#include <iostream>
#include <cmath>
using namespace std;
bool isPrime(int x) {
for(int i=2; i<=sqrt(x); i++)
if(x%i == 0) return false;
return true;
}
int main() {
int n;
cin >> n;
for(int i=n/2; ; i++) {
if(isPrime(i) && isPrime(n-i)) {
cout << i*(n-i);
break;
}
}
return 0;
}
解题思路
-
从n/2开始寻找最近的质数对
-
利用数学性质:差最小的质数对乘积最大
知识点
-
质数判断、数学优化
题目14:特殊队列问题
题目描述
队伍排队时,每次2/3/4/5/6人一组都会余1人,7人一组正好。求最少可能人数。
输入样例
无输入
输出样例
复制
301
数据范围
答案唯一解
参考代码
#include <iostream>
using namespace std;
int main() {
int times = 0;
while(true) {
times += 7;
if(times%2==1 && times%3==1 &&
times%4==1 && times%5==1 && times%6==1) {
cout << times;
break;
}
}
return 0;
}
解题思路
-
步长7递增(保证7人一组整除)
-
验证其他分组余数条件
知识点
-
同余定理、步长优化
题目15:统计特殊余数的个数
题目描述
统计1到100之间(包含1和100)所有整数i满足i % 8 == 1的次数。
输入输出样例
输入样例:无输入
输出样例:
13
参考代码1
int main() {
int i = 100, x = 0, y = 0;
while (i > 0) {
i--;
x = i % 8;
if (x == 1) y++;
}
cout << y << endl;
return 0;
}
解题思路
-
逆序遍历:从100开始逆序遍历到1,检查每个数对8取余是否为1。
-
计数器累加:满足条件时计数器
y加1。
知识点
循环结构、模运算、条件判断。
题目16:区间质数统计
题目描述
输入两个整数m和n(2 ≤ m ≤ n ≤ 1000),输出区间[m, n]内的质数个数。
输入输出样例
输入样例:
2 10
输出样例:
4
参考代码
int main() {
int m, n, sum = 0;
cin >> m >> n;
for (int i = m; i <= n; i++) {
bool is_prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
is_prime = false;
break;
}
}
if (is_prime) sum++;
}
cout << sum << endl;
return 0;
}
解题思路
-
遍历区间:对区间内每个数进行质数判断。
-
质数判定:若存在除1和自身外的因数,则不是质数。
知识点
双重循环、质数判断逻辑、布尔标志位。
题目17:分解质因数
题目描述
输入一个正整数num(2 ≤ num ≤ 10000),将其分解为质因数相乘的形式输出。
输入输出样例
输入样例1:
6
输出样例1:
6=2*3
输入样例2:
60
输出样例2:
60=2*2*3*5
参考代码
int main() {
int num;
cin >> num;
cout << num << "=";
for (int i = 2; i <= num; i++) {
while (num % i == 0) {
cout << i;
num /= i;
if (num != 1) cout << "*";
}
}
return 0;
}
解题思路
-
从小到大试除:从2开始依次尝试整除输入的数。
-
循环分解:若当前数i是因数,则持续分解直至无法整除。
知识点
质因数分解、循环嵌套、字符串拼接。
题目18:寻找回文质数
题目描述
输入一个正整数n(n ≥ 11),输出所有小于等于n且同时是回文数和质数的数。
输入输出样例
输入样例1:
20
输出样例1:
11是回文数
输入样例2:
1000
输出样例2:
11是回文数 101是回文数 131是回文数 151是回文数 ...
参考代码4
int main() {
int n;
cin >> n;
for (int i = 11; i <= n; i++) {
int reversed = 0, original = i;
while (original != 0) {
reversed = reversed * 10 + original % 10;
original /= 10;
}
if (reversed == i) {
bool is_prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
is_prime = false;
break;
}
}
if (is_prime) cout << i << "是回文数 ";
}
}
return 0;
}
解题思路
-
回文数判断:反转数字与原数比较。
-
质数校验:对回文数进行质数判定。
知识点
数字反转、复合条件判断、算法效率优化。
题目19:可逆质数
题目描述
输出1000以内所有可逆质数(即质数反转后仍为质数),每行最多10个数。
输入输出样例
输入样例:无输入
输出样例(部分):
2 3 5 7 11 13 17 ...
参考代码
int main() {
int c = 0;
for (int m = 2; m <= 1000; m++) {
bool prime1 = true;
for (int i = 2; i <= sqrt(m); i++) {
if (m % i == 0) {
prime1 = false;
break;
}
}
if (prime1) {
int reversed = 0, temp = m;
while (temp > 0) {
reversed = reversed * 10 + temp % 10;
temp /= 10;
}
bool prime2 = true;
for (int i = 2; i <= sqrt(reversed); i++) {
if (reversed % i == 0) {
prime2 = false;
break;
}
}
if (prime2) {
cout << m << "\t";
c++;
if (c % 10 == 0) cout << endl;
}
}
}
return 0;
}
解题思路
-
质数筛选:遍历2到1000,筛选质数。
-
反转验证:反转质数后再次进行质数判断。
知识点
质数筛法、数字反转、格式化输出。
题目20:最大公约数(枚举法)
题目描述
输入两个正整数a和b,输出它们的最大公约数。
输入输出样例
输入样例1:
12 18
输出样例1:
6
输入样例2:
7 5
输出样例2:
1
参考代码
int main() {
int a, b;
cin >> a >> b;
for (int i = min(a, b); i >= 1; i--) {
if (a % i == 0 && b % i == 0) {
cout << i << endl;
return 0;
}
}
return 0;
}
解题思路
从两数较小值开始递减遍历,找到第一个能同时整除两数的数。
知识点
枚举法、循环控制、数学基础。
题目21:最大公约数(辗转相除法)
题目描述
输入两个正整数m和n,用辗转相除法求它们的最大公约数。
输入输出样例
输入样例1:
24 36
输出样例1:
12
输入样例2:
17 13
输出样例2:
1
参考代码
int main() {
int m, n, r;
cin >> m >> n;
r = m % n;
while (r != 0) {
m = n;
n = r;
r = m % n;
}
cout << n << endl;
return 0;
}
解题思路
-
反复取余:用较大数除以较小数,余数替换较大数。
-
终止条件:余数为0时,当前除数即为最大公约数。
知识点
欧几里得算法、循环与条件判断。
题目22:铺地板的最优方案
题目描述
已知房间长75厘米,宽60厘米。需用正方形瓷砖铺满地面,且必须用整块瓷砖。求瓷砖边长的所有可能值,并输出最大边长时需要的瓷砖数。
输入输出样例
输入样例:无输入
输出样例:
1 3 5 15 15
参考代码
int main() {
int x = 75, y = 60, a;
for (int i = 1; i <= min(x, y); i++) {
if (x % i == 0 && y % i == 0) {
cout << i << " ";
a = i;
}
}
cout << endl << (75 * 60) / (a * a);
return 0;
}
解题思路
-
求公约数:瓷砖边长必须是长和宽的公约数。
-
计算面积:最大公约数对应瓷砖面积最小,数量最少。
知识点
公约数应用、实际问题建模。
题目23:约分三角函数
题目描述
输入三角形的三边长a、b、c(构成直角三角形),输出最短边与最长边的比值的最简分数形式。
输入输出样例
输入样例1:
3 4 5
输出样例1:
3/5
输入样例2:
6 8 10
输出样例2:
3/5
参考代码
int main() {
int a, b, c, max, min, r;
cin >> a >> b >> c;
max = a > b ? a : b;
max = c > max ? c : max;
min = a < b ? a : b;
min = c < min ? c : min;
a = min;
c = max;
r = c % a;
while (r != 0) {
c = a;
a = r;
r = c % a;
}
cout << min / a << "/" << max / a;
return 0;
}
解题思路
-
找最值:确定最短边和最长边。
-
约分:用辗转相除法求最大公约数进行约分。
知识点
最值判断、分数约分、数学逻辑。
