🌟 C++ 循环嵌套·笔记 🌟
核心概念:循环嵌套就是“一个循环里面再套一个循环”。外面的循环跑一次,里面的循环就要跑整整一圈。
🏗️ 1. 认识循环嵌套:操场跑步与圈数
想象一下学校的操场:
- 外层循环:代表“第几天”训练(比如周一到周五,循环5次)。
- 内层循环:代表“当天跑多少圈”(比如每天跑4圈,循环4次)。
代码结构:
for(intday=1;day<=5;day++){// 外层:5天cout<<"今天是第"<<day<<"天,开始跑步!"<<endl;for(intlap=1;lap<=4;lap++){// 内层:4圈cout<<"跑了第"<<lap<<"圈"<<endl;}cout<<"今天跑完了,休息!"<<endl;}注意:内层循环要缩进(空格),这样看起来像房子里套着小房子,逻辑更清晰!
📐 2. 图形打印题:画矩形与三角形 (对应文档题目 1097, 2027)
图形题是循环嵌套的“入门砖”。
题目:画矩形 (1097)
- 任务:输入高
h和宽w,用*画一个实心矩形。 - 思路:
- 外层循环 (控制行):跑
h次(有多少行)。 - 内层循环 (控制列):每次跑
w次(每行有多少个星号)。 - 换行:内层循环跑完一次(一行画完了),记得
cout << endl;换行。
- 外层循环 (控制行):跑
#include<iostream>usingnamespacestd;intmain(){inth,w;cin>>h>>w;for(inti=1;i<=h;i++){// 外层:行for(intj=1;j<=w;j++){// 内层:列cout<<"*";// 打印星号,不换行}cout<<endl;// 一行打印结束,换行!}return0;}题目:三角形 (2027)
- 变通:如果是直角三角形(比如第i行打印i个星号),内层循环的上限不再是固定的
w,而是变化的i。
for(inti=1;i<=n;i++){// i从1到nfor(intj=1;j<=i;j++){// j从1到icout<<"*";}cout<<endl;}🔍 3. 枚举查找题:百钱买百鸡与找素数 (对应文档题目 2028, 2030, 1099)
当一个问题有多个未知数,或者需要“一个一个试”时,我们用循环嵌套来当“超级侦探”。
题目:百钱买百鸡 (2028)
- 题目意思:公鸡5块钱一只,母鸡3块钱一只,小鸡1块钱三只。用100块钱买100只鸡,问怎么买?
- 思路:这有三个未知数(公鸡数x、母鸡数y、小鸡数z)。我们可以用三重循环,把所有可能的情况都试一遍!
- 优化:因为钱和鸡的数量都有限,我们可以根据“总价不超过100”来缩小循环范围。
#include<iostream>usingnamespacestd;intmain(){// x:公鸡, y:母鸡, z:小鸡for(intx=0;x<=20;x++){// 公鸡最多买20只(100/5)for(inty=0;y<=33;y++){// 母鸡最多买33只intz=100-x-y;// 小鸡数量(总数是100只)if(z%3==0&&5*x+3*y+z/3==60){// 检查小鸡数量是否合法,且总价是否为100cout<<x<<" "<<y<<" "<<z<<endl;}}}return0;}题目:找素数 (2030) / 第n小的质数 (1099)
- 思路:判断一个数
i是不是素数,需要拿从2到i-1的所有数去试除。- 外层循环:遍历从
2到n的所有数字。 - 内层循环:尝试用
2到sqrt(i)(或者i-1)去整除i。
- 外层循环:遍历从
#include<iostream>#include<cmath>usingnamespacestd;intmain(){intm,n;cin>>m>>n;for(inti=m;i<=n;i++){// 遍历范围内的每个数boolisPrime=true;// 假设i是素数for(intj=2;j<=sqrt(i);j++){// 尝试除以jif(i%j==0){// 如果能整除isPrime=false;// 说明不是素数break;// 跳出内层循环(不用再试了)}}if(isPrime&&i>1){// 注意:1不是素数cout<<i<<endl;}}return0;}🔢 4. 数字处理题:水仙花数与分解质因数 (对应文档题目 2029, 2032, 1098)
这类题目需要把一个数“拆开”或者“分解”。
题目:水仙花数 (2029)
- 定义:一个三位数,它的各位数字的立方和等于它本身(例如:13+53+33=1531^3+5^3+3^3=15313+53+33=153)。
- 技巧:如何拆分数字?
- 个位 =
num % 10 - 十位 =
(num / 10) % 10 - 百位 =
num / 100
- 个位 =
#include<iostream>usingnamespacestd;intmain(){intn;cin>>n;for(inti=100;i<n;i++){// 遍历100到nintge=i%10;intshi=(i/10)%10;intbai=i/100;if(ge*ge*ge+shi*shi*shi+bai*bai*bai==i){cout<<i<<endl;}}return0;}题目:分解质因数 (2032, 1098)
- 思路:拿一个数
n,从最小的质数2开始试除。- 只要
n能被i整除,就把i打印出来,并把n除以i。 - 如果不能整除,
i就加1,继续试。 - 直到
i大于n为止。
- 只要
#include<iostream>usingnamespacestd;intmain(){intn;cin>>n;cout<<n<<"=";inttemp=n;boolfirst=true;// 控制输出格式(第一个数前面不加*)for(inti=2;i<=temp;){if(n%i==0){if(!first)cout<<"*";cout<<i;n=n/i;// n变小了first=false;}else{i++;// 试下一个数}}return0;}💡 5. 高效技巧:累加与累乘 (对应文档题目 2033, 1091, 1092)
有时候我们需要计算1! + 2! + 3! + ... + n!。
- 错误做法:写两个嵌套循环,内层每次都从头算
1*2*3*...*i。这样太慢了! - 聪明做法:利用上一次的结果!
1! = 12! = 1! * 23! = 2! * 3- 所以,我们可以在外层循环里维护一个
factorial变量,每次乘以当前的i即可。
#include<iostream>usingnamespacestd;intmain(){intn;cin>>n;longlongsum=0;// 存总和longlongfactorial=1;// 存当前的阶乘值for(inti=1;i<=n;i++){factorial=factorial*i;// 计算i的阶乘sum=sum+factorial;// 累加到总和}cout<<sum<<endl;return0;}📝 总结:循环嵌套的“三大家族”
| 题型 | 典型题目 | 核心思路 |
|---|---|---|
| 图形打印 | 画矩形、三角形 | 外层控制行,内层控制列,记得换行。 |
| 枚举查找 | 百钱买百鸡、找素数 | 把所有可能的情况都试一遍(暴力美学),找到符合条件的就输出。 |
| 数字处理 | 水仙花数、分解质因数 | 利用%和/拆分数字,或者利用循环试除。 |
提示:
循环嵌套就像俄罗斯套娃,一层包着一层。做题时,先想清楚“外层要干什么”,再想清楚“内层要干什么”。多画图、多调试!