【杂记】之语法学习第二课循环与数组

while 循环

回顾上节的最后我们学了用 if 进行判断,

if(条件)
{
    操作;
}

while 循环也是一个类似的结构:

while(条件)
{
	操作;
}

区别在于 while 没有类似 else 的操作,而且如果满足条件,则会重复执行大括号内的操作;而if只会执行其中的一次操作。

在这里插入图片描述

题目描述

给定一个小于等于 100010001000 的正整数 nnn ,求 111nnn 中所有数的累加和。

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n ;
	scanf("%d" ,&n);
	int i = 1 , sum = 0 ;
	while(i <= n)
	{
		sum += i ;
		i ++ ;
	}
	printf("%d" ,sum) ;
	return 0 ;
}

数学方法可以直接考虑利用等差数列求和公式 (首项+末项)×项数2{(首项 + 末项) \times 项数}\over 22(首项+末项)×项数 ,但是这个题数据范围比较小,所以也可以通过模拟的方式来完成这个过程。

注意一定要给 sum 赋初始值0

当我们在主函数内声明变量时,通常没有固定的初始值,我们将 iii111 加到 nnn ,每次加一,实现了从 111nnn 所有整数的枚举,然后将这些数全部加到 sumsumsum 上,则 sumsumsum 即为所求的答案。

题目描述

给出 nnnnnn 个整数 aia_iai,求这 nnn 个整数中最小值是什么。

输入格式

第一行输入一个正整数 nnn,表示数字个数。

第二行输入 nnn 个非负整数,表示 a1,a2…ana_1,a_2 \dots a_na1,a2an,以空格隔开。

输出格式

输出一个非负整数,表示这 nnn 个非负整数中的最小值。

样例输入
8
1 9 2 6 0 8 1 7
样例输出
0
提示

数据保证,n≤100n\le100n1000≤ai≤10000\le a_i \le 10000ai1000

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n , a , ans = 1000000000;
	scanf("%d" ,&n);
	while(n)
	{
		scanf("%d" ,&a) ;
		if(ans > a) ans = a ;
		n -- ;
	}
	printf("%d" ,ans) ;
	return 0 ;
}

此时的 nnn 起到计数的作用,当然也可以另外设置一个 iii 写成

int i = 1 ;
while(i <= n)
{
	scanf("%d" ,&a) ;
	if(ans > a) ans = a ;
	i ++ ;
}

或者利用 n ++ 这一写法先调用后修改的性质,写成

	while(n --)
	{
		scanf("%d" ,&a) ;
		if(ans > a) ans = a ;
	}

for循环

forforfor 循环结构看起来可能更麻烦,但是也挺好理解的:

for(初始; 判断 ; 更新)
{
  操作;
  //循环体
}

当进入 forforfor 循环时先初始化,然后判断条件是否成立,若不成立则退出循环,若成立则执行相应操作,执行完操作后更新,再次判断条件是否成立,若不成立则退出,若成立则再次进行相应操作。在这里插入图片描述
我们用 forforfor 循环再写一遍上面两道题

题目描述

给定一个小于等于 100010001000 的正整数 nnn ,求 111nnn 中所有数的累加和。

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n , sum = 0 ;
	scanf("%d" ,&n);
    for(int i = 1; i <= n ; i ++)
    {
    	sum += i ;
	}
	printf("%d" ,sum) ;
	return 0 ;
}

其中 forforfor 循环后的大括号也是可加可不加,如果只进行单个操作不用加,多个操作括起来。

题目描述

给出 nnnnnn 个整数 aia_iai,求这 nnn 个整数中最小值是什么。

输入格式

第一行输入一个正整数 nnn,表示数字个数。

第二行输入 nnn 个非负整数,表示 a1,a2…ana_1,a_2 \dots a_na1,a2an,以空格隔开。

输出格式

输出一个非负整数,表示这 nnn 个非负整数中的最小值。

样例输入
8
1 9 2 6 0 8 1 7
样例输出
0
提示

数据保证,n≤100n\le100n1000≤ai≤10000\le a_i \le 10000ai1000

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n , a , ans = 1000000000;
	scanf("%d" ,&n);
	for(int i = 1 ; i <= n ; i ++)
	{
		scanf("%d" ,&a) ;
		if(a < ans) ans = a ; 
	}
	printf("%d" ,ans) ;
	return 0 ;
}

此时的 iii 没有参与任何运算,只是用来计数也是可以的。

局部变量

注意,在两个 forforfor 循环的举例代码中,我们的 iii 是在 forforfor 循环的初始化部分声明的变量,因此只能作为局部变量在大括号内使用,而不能在循环结构之外随意调用!

break; 与 continue;

break; 操作用在循环体中,表示退出循环。

continue;操作用在循环体中,表示跳过本次循环的剩余操作,进入下一次循环。

当多层循环嵌套使用时,以上两项操作若在内层循环中,只会对内层循环产生影响。

继续做题巩固一下

题目描述

已知:Sn=1+12+13+…+1nS_n= 1+\dfrac{1}{2}+\dfrac{1}{3}+…+\dfrac{1}{n}Sn=1+21+31++n1。显然对于任意一个整数 kkk,当 nnn 足够大的时候,Sn>kS_n>kSn>k

现给出一个整数 kkk,要求计算出一个最小的 nnn,使得 Sn>kS_n>kSn>k

输入格式

一个正整数 kkk

输出格式

一个正整数 nnn

样例输入
1
样例输出
2

提示

【数据范围】

对于 100%100\%100% 的数据,1≤k≤151\le k \le 151k15

#include <bits/stdc++.h>
using namespace std;
int main()
{
	double ans = 0 , k ;
	int n = 1 ;
	scanf("%lf" ,&k) ;
	for( ; ans <= k ; n ++)
		ans += 1.0 / n ;
	printf("%d" ,n - 1) ;
	return 0;
}

这个写法中 nnn 在最后输出,因此设为全局变量,同时 forforfor 循环中无论是 初始化判断 还是 更新 其实都是可以省略掉的,但是该有的结构还是要有,比如两个分号。

双层循环

题目描述

给出 nnn,请输出一个直角边长度是 nnn 的数字直角三角形。所有数字都是 222 位组成的,如果没有 222 位则加上前导 000

输入格式

输入一个正整数 nnn

输出格式

输出如题目要求的数字直角三角形。

样例输入
5
样例输出
0102030405
06070809
101112
1314
15
提示

数据保证,1≤n≤131\le n\le131n13

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int n , tot = 1;
	scanf("%d" ,&n) ;
	for(int i = 1 ; i <= n ; i ++)//第i层
	{
		for(int j = i ; j <= n ; j ++)//第i层有n - i + 1 个数,因此 j 从 i 到 n
		{
			printf("%02d" ,tot) ;
			tot ++ ;
		}
		printf("\n") ;
	}
	return 0;
}

这个就体现了双重循环,每次进入内层的 j循环 时都重新把 jjj 初始化成了当前的 iii ,用 tottottot 记录这个数字三角形到了数字几。

printf("%02d" ,tot) ; 的写法就是说不满两位的数字通过补前导 000 的方式补成两位。

然后每次输出完当前的那一层就换行。

数组

当我们需要 333 个变量时可以声明 a,b,ca , b , ca,b,c ,那么当我们需要 100100100 个时呢?

可以 int a[100]; 意思是声明整型数组 aaa 中括号里数字类比数列的下标,调用时就 a[1],a[2],a[3]a[1],a[2],a[3]a[1],a[2],a[3] 这样的用。

int a[100] ; //声明一个包含100个元素的数组
a[1] = 666 ; //赋值与正常变量一样
int k = 5 ;
a[k] = 123 ;//下标可以是一个数,也可以是变量
a['a'] = 456 ; //甚至可以是一个字符,相当于其对应ascii码值
a[k + 1] = a[k] + a[1] ;
printf("%d" ,a[k + 1]) ; //输出

特别的,我们用什么样的 关键字 声明这个数组,这个数组就是什么数据类型的,就是说也可以用 char 声明字符型数组 或者 用 double 声明浮点型数组;基于下标可以是变量这一特性,也很容易地可以和 循环 结合起来使用;注意: 数组的下标是从 000 开始,到 n−1n - 1n1 结束,即声明一个 int a[100] 这样的数组,只有下标为从 000999999 之间的整数时才是合法的!

题目描述

陶陶家的院子里有一棵苹果树,每到秋天树上就会结出 101010 个苹果。苹果成熟的时候,陶陶就会跑去摘苹果。陶陶有个 303030 厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。

现在已知 101010 个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹果的数目。假设她碰到苹果,苹果就会掉下来。

输入格式

输入包括两行数据。第一行包含 101010100100100200200200 之间(包括 100100100200200200)的整数(以厘米为单位)分别表示 101010 个苹果到地面的高度,两个相邻的整数之间用一个空格隔开。第二行只包括一个 100100100120120120 之间(包含 100100100120120120)的整数(以厘米为单位),表示陶陶把手伸直的时候能够达到的最大高度。

输出格式

输出包括一行,这一行只包含一个整数,表示陶陶能够摘到的苹果的数目。

样例输入
100 200 150 140 129 134 167 198 200 111
110
样例输出
5
#include <bits/stdc++.h>
using namespace std;
int apple[20];
int main()
{
	for(int i = 1 ; i <= 10 ; i ++)
		scanf("%d" ,&apple[i]) ;
	int tall , high , ans = 0 ;
	scanf("%d" ,&tall) ;
	high = tall + 30;
	for(int i = 1 ; i <= 10 ; i ++)
		if(high >= apple[i]) ans ++;
	printf("%d" ,ans) ;
	return 0;
}

学了 循环数组 之后就不需要声明 101010 个变量挨个输入了,在 主函数 内声明的变量在不赋初始值的情况下可能是任意数,在 主函数 外声明变量时默认为 000

二维数组

思考我们 一维数组 只是多一个下标,其实还可以有 二维数组 ,即int a[110][110]; 这样的,可以思考为 一维数组 是一个 数列二维数组 是一个矩阵,有横坐标和纵坐标,可以类比线代里的矩阵。

想要访问每个位置可以类比一维数组时用循环里的变量当做下标,二维数组就可以用双重循环来访问每个下标。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值