循环嵌套
循环嵌套的使⽤
while , do while , for ,这三种循环往往会嵌套在⼀起才能更好的解决问题,就是我们所说的:循环嵌套。这三种循环都可以任意嵌套使⽤
⽐如:
写⼀个代码,打印⼀个乘法⼝诀表
1*1= 1
1*2= 2 2*2= 4
1*3= 3 2*3= 6 3*3= 9
1*4= 4 2*4= 8 3*4=12 4*4=16
1*5= 5 2*5=10 3*5=15 4*5=20 5*5=25
1*6= 6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7= 7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8= 8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9= 9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
- 打印的内容是分为9⾏的,第1⾏打印1项,第2⾏打印2项,第3⾏打印3项,以此类推,第9⾏打印9项。
- 每⼀⾏的信息,每⼀项的第⼀个乘数和列号是⼀致的,每⼀项的第⼆个乘数和⾏号是⼀致的,两个乘数的积就是第三个数。
- 打印9⾏,我们可以使⽤循环解决,总共循环9次,每次进⼊循环打印⼀⾏,循环变量使⽤ i 来控制, i 从1开始,循环到9
- 打印⼀⾏。第 i ⾏是有 i 项组成的,这 i 项的打印也可以写成循环来完成。使⽤循环变量 j , j 从1开始,⼀致循环到 i ,正好循环 i 次,正好打印 i 项。同时每⼀⾏打印完后还要换⾏。
- 输出的效果中,
i*j
的结果如果是2位数,才有右对⻬,不够2位数的情况,使⽤空格补⻬。所以这⾥就得使⽤ %2d 这样的输出格式控制了。
#include <iostream>
using namespace std;
#include <cstdio>
int main()
{
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= i; j++)
{
printf("%d*%d=%2d ", j, i, j * i);
}
cout << endl;
}
return 0;
}
练习
乘法表
#include <iostream>
using namespace std;
#include <cstdio>
int main()
{
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= i; j++)
{
printf("%d*%d=%2d ", j, i, j * i);
}
cout << endl;
}
return 0;
}
像题⽬要求的这种情况,就得使⽤两层循环嵌套来解决,外层循环负责控制打印⼏⾏,内部循环负责控制每⼀⾏打印⼏项。
包含数字9的数
#include <iostream>
using namespace std;
int main()
{
int cnt = 0;
for (int i = 1; i <= 2019; i++)
{
int n = i;
while (n)
{
if (n % 10 == 9)
{
cnt++;
break;
}
n /= 10;
}
}
cout << cnt << endl;
return 0;
}
在多层嵌套的循环中也可以使⽤break,但是要注意,⼀个break只能跳出⾃⼰所在的循环,⽆法⼀次性跳出所有的循环
B2064 斐波那契数列
#include <iostream>
using namespace std;
int n;
int main()
{
cin >> n;
int a = 0;
while (n--)
{
cin >> a;
int i = 1, j = 1, k = 1;
while (a >= 3)
{
k = i + j;
i = j;
j = k;
a--;
}
cout << k << endl;
}
return 0;
}
B2079 求出 e 的值
#include <iostream>
#include <cstdio>
using namespace std;
int n;
int main()
{
cin >> n;
double e = 1;
for (int j = 1; j <= n; j++)
{
long long x = 1;
for (int i = 1; i <= j; i++)
{
x *= i;
}
e += 1.0 / x;
}
printf("%.10f", e);
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int n = 0;
cin >> n;
int i = 1;
double e = 1;
long long fac = 1;
while (i <= n)
{
fac *= i;
e += 1.0 / fac;
i++;
}
printf("%.10lf\n", e);
return 0;
}
三角形
#include <iostream>
using namespace std;
int n;
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
cout << "*";
}
cout << endl;
}
return 0;
}
B2083 画矩形
#include <iostream>
using namespace std;
int a, b, f;
char c;
int main()
{
cin >> a >> b >> c >> f;
if (f == 0)
{
for (int i = 1; i <= a; i++)
{
for (int j = 1; j <= b; j++)
{
if (i == 1 || i == a || j == 1 || j == b)
cout << c;
else
cout << " ";
}
cout << endl;
}
}
else
{
for (int i = 1; i <= a; i++)
{
for (int j = 1; j <= b; j++)
{
cout << c;
}
cout << endl;
}
}
return 0;
}
如果我们仔细去琢磨上⾯的代码,会发现 if 和 else 中都是打印图案,区别在于实⼼还是空⼼,实⼼和空⼼的区别⼜在于中间区域,其实边上的⼀圈实⼼和空⼼是⼀样的。所以我们在实现的时候,边上⼀圈打印字符,剩余的区域,做⼀个判断,如果是实⼼打印c,如果是空⼼就打印空格就好了,那么就有了下⾯简化的写法。
#include <iostream>
using namespace std;
int a, b, f;
char c;
int main()
{
cin >> a >> b >> c >> f;
for (int i = 1; i <= a; i++)
{
for (int j = 1; j <= b; j++)
{
if (i == 1 || i == a || j == 1 || j == b)
cout << c;
else
{
if (f == 0)
cout << " ";
else
cout << c;
}
}
cout << endl;
}
return 0;
}
B2085 第 n 小的质数
解析:
- 质数⼜称素数。⼀个⼤于1的⾃然数,除了1和它自身外,不能被其他⾃然数整除的数叫做质数。
- 第n⼩的质数,其实就是从⼩到⼤的第n个质数。
伪代码
int i = 2;
int cnt = 0;
while (1)
{
判断i是否是素数
试除:拿2~i-1之间的数组去试除i
如果2-i-1之间有数字能整除i,则i不是素数
如果2-i-1之间没有任何一个数字能整除i,则i是素数
如果i是素数,cnt++
if (cnt == n)
break;
i++;
}
循环停止的时候,i就是第n个素数
#include <iostream>
using namespace std;
int n;
int main()
{
cin >> n;
int i = 2;
int cnt = 0;
while (1)
{
int flag = 1;
for (int j = 2; j <= i-1; j++)
{
if (i % j == 0)
{
flag = 0;
break;
}
}
if (flag == 1)
cnt++;
if (cnt == n)
break;
i++;
}
cout << i << endl;
return 0;
}
“Time Limit Exceeded”(TLE,超时)是⼀个在编程竞赛和在线评测平台(如LeetCode、Codeforces、HackerRank等)中常⻅的错误信息。它意味着程序在执⾏过程中超过了给定的最⼤运⾏时间限制,⽽未能在规定时间内得出结果。
如果 n 有⼀个因⼦ a ,那么必然存在另⼀个因⼦ b ,使得 n = a × b 。如果 a 和 b 都⼤于 n \sqrt{ n } n,那么 a×b 将会⼤于 n ,这与 n=a×b ⽭盾。因此⾄少有⼀个因⼦不会超过的。
#include <iostream>
using namespace std;
#include <cmath>
int n;
int main()
{
cin >> n;
int i = 2;
int cnt = 0;
while (1)
{
int flag = 1;
for (int j = 2; j <= sqrt(i); j++)
{
if (i % j == 0)
{
flag = 0;
break;
}
}
if (flag == 1)
cnt++;
if (cnt == n)
break;
i++;
}
cout << i << endl;
return 0;
}
水仙花数
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
for (int i = 100; i <= 999; i++)
{
int sum = 0;
int tmp = i;
while (tmp)
{
sum += pow(tmp % 10, 3);
tmp /= 10;
}
if (sum == i)
cout << i << endl;
}
return 0;
}
pow函数,可以⽤计算次⽅的函数, pow(x, y) 返回的是 x 的 y 次⽅的值
pow 函数需要⼀个头⽂件 <cmath>