01 03 07 第一部分 C++编程知识 分支语句与循环语句 for循环

第一部分  C++编程知识  第三章 分支语句与循环语句  

第七节  for循环

一、for循环语法形式

for (表达式1; 表达式2; 表达式3)
	语句;	//如果循环体想包含更多的语句,可以加上大括号{}

        表达式1用于循环变量的初始化。

        表达式2用于循环结束条件的判断。

        表达式3用于循环变量的调整。


、for循环的执行流程

        首先执行表达式1初始化循环变量。接下来就是执行表达式2的判断部分,表达式2的结果如果为假,则循环结束;表达式2的结果如果为真,则执行循环语句。循环语句执行完后,再去执行表达式3,调整循环变量,然后再去执行判断表达式2的结果是否为0,决定循环是否继续。整个循环的过程中,表达式1初始化部分只被执行1次,剩下的就是表达式2、循环语句、表达式3在循环。


三、for循环的实践

        下面我们可以使用for循环写一个简单的代码,来观察for循环的使用。

        实现“在屏幕上打印1~10的值”的功能,代码如下:

#include <cstdio>
int main(){
	int num = 0;
	for (num = 1; num <= 10; ++num)
{
		printf("%d ", num);
	}
	return 0;
}

        这段代码就可以实现“在屏幕上打印1~10的值”的功能了,在使用上是比while语句更简单的。值得注意的是,有可能会将上面这段代码写成下面这样:

#include <cstdio>
int main(){
	for (int num = 1; num <= 10; ++num){
		printf("%d ", num);
	}
	return 0;
}

        这两段代码的区别是,第一段代码中for循环结束后,num的值还可以继续使用,但是代码2中for循环的外边num变量是不可以使用的,num变量只能在for循环中使用。


四、while循环和for循环的对比

        for 和 while 在实现循环的过程中都有初始化、判断、调整这三个部分,但是 for 循环的三个部分非常集中,便于代码的维护,而如果代码较多的时候 while 循环的三个部分就比较分散,所以从形式上 for 循环要更优一些。


五、 for循环的应用实例

        通过上面的学习,接下来我们可以实现一个比较复杂的功能了——“计算1~100之间3的倍数的数字之和”下面是我解决这个问题所编写的代码:

#include <cstdio>
int main(){
	int num = 0;
	int sum = 0;
	for (num = 1; num <= 100; ++num){
		if (0 == num % 3)
			sum = sum + num;
	}
	printf("1到100之间3的倍数的数字之和为:%d", sum);
	return 0;
}

        当然解决这个问题的办法不止一种,上面的解决方法是最正规按照题目要求的逻辑完成,如果我们换一种算法,也可以直接产生3的倍数,省去了很多次的循环和判断,使代码的效率更高,这是优化后的代码:

#include <stdio.h>
int main(){
	int num = 0;
	int sum = 0;
	for (num = 3; num <= 100; num += 3)
	{
		sum = sum + num;
	}
	printf("1到100之间3的倍数的数字之和为:%d", sum);
	return 0;
}

练习一

        班上有学生若干名,给出每名学生的年龄(整数),求班上所有学生的平均年龄,保留到小数点后两位。

· 输入格式:第一行有一个整数n(1 ≤ n ≤ 100),表示学生的人数。其后n行每行有1个整数,表示每个学生的年龄,取值为15到25。

· 输出格式:输出一行,该行包含一个浮点数,为要求的平均年龄,保留到小数点后两位。

参考答案

#include <iostream>
#include <iomanip> 
using namespace std;
int num, score;
int main(){
	cin >> num;
	int i = 1;
	int sum = 0;
	for (i = 1; i <= num; i++){
		cin >> score;
		sum += score;
	}
	cout << fixed << setprecision(2) << sum * 1.0 / num << endl;
	return 0;
}

练习二

        2008年北京奥运会,A国的运动员参与了n天的决赛项目(1 ≤ n ≤ 100)。现在要统计一下A国所获得的金、银、铜牌数目及总奖牌数。输入第1行是A国参与决赛项目的天数n,其后n行,每一行是该国某一天获得的金、银、铜牌数目(不超过100)。输出4个整数,为A国所获得的金、银、铜牌总数及总奖牌数。

· 输入格式:第1行是A国参与决赛项目的天数n,其后n行,每一行是该国某一天获得的金、银、铜牌数目,以一个空格分开。

· 输出格式:输出1行,包括4个整数,为A国所获得的金、银、铜牌总数及总奖牌数,以一个空格分开。

参考输入输出

参考答案

#include <iostream>
using namespace std;
int a, b, c, day;
int suma, sumb, sumc;
int main()
{
	cin >> day;
	int i = 1;
	for (i = 1; i <= day; i++)
	{
		cin >> a >> b >> c;
		suma += a;
		sumb += b;
		sumc += c;
	}
	int sum = suma + sumb + sumc;
	cout << suma << ' ' << sumb << " " << sumc << ' ' << sum;
	return 0;
}

练习三

        鸡尾酒疗法,原指“高效抗逆转录病毒治疗”(HAART),由美籍华裔科学家何大一于 1996 年提出,是通过三种或三种以上的抗病毒药物联合使用来治疗艾滋病。该疗法的应用可以减少单一用药产生的抗药性,最大限度地抑制病毒的复制,使被破坏的机体免疫功能部分甚至全部恢复,从而延缓病程进展,延长患者生命,提高生活质量。

        人们在鸡尾酒疗法的基础上又提出了很多种改进的疗法。为了验证这些治疗方法是否在疗效上比鸡尾酒疗法更好,可用通过临床对照实验的方式进行。

        假设鸡尾酒疗法的有效率为 x,新疗法的有效率为 y,如果 y − x 大于5%,则效果更好,如果x − y 大于 5%,则效果更差,否则称为效果差不多。

        下面给出 n 组临床对照实验,其中第一组采用鸡尾酒疗法,其他n−1 组为各种不同的改进疗法。请写程序判定各种改进疗法效果如何。

· 输入格式:第一行为整数 n(1 < n ≤ 20);其余 n 行每行两个整数,第一个整数是临床实验的总病例数(小于等于10000),第二个整数是疗效有效的病例数。这 n 行数据中,第一行为鸡尾酒疗法的数据,其余各行为各种改进疗法的数据。

· 输出格式:有 n−1 行输出,分别表示对应改进疗法的效果:如果效果更好,输出 better;如果效果更差,输出 worse;否则输出 same。

参考答案

#include <iostream>
using namespace std;
int n, a1, b1;
int main(){
	cin >> n;
	int i = 2;
	cin >> a1 >> b1;
	double jixiao = b1 * 1.0 / a1;
	for (i = 2; i <= n; i++){
		int a2 = 0;
		int b2 = 0;
		cin >> a2 >> b2;
		double xinxiao = b2 * 1.0 / a2;
		if (xinxiao - jixiao >= 0.05)
			cout << "better" << endl;
		else if (jixiao - xinxiao >= 0.05)
			cout << "worse" << endl;
		else
			cout << "same" << endl;
	}
	return 0;
}

本题注意点

1、在算法竞赛中,可能会涉及到部分题目题目部分很长,一定要耐心审题,也不要惧怕题目难度过高。

2、完成本题需要严格遵守以下几点:输入输出格式的严格遵循、浮点数除法的正确实现、循环逻辑的正确控制、浮点数比较的精度问题以及边界条件的处理。


练习四

        救生船从大本营出发,营救若干屋顶上的人回到大本营,屋顶数目以及每个屋顶的坐标和人数都将由输入决定,求出所有人都到达大本营并登陆所用的时间。

        在直角坐标系的原点是大本营,救生船每次从大本营出发,救了人之后将人送回大本营。坐标系中的点代表屋顶,每个屋顶由其位置坐标和其上的人数表示。救生船每次从大本营出发,以速度50米/分钟驶向下一个屋顶,达到一个屋顶后,救下其上的所有人,每人上船1分钟,船原路返回,达到大本营,每人下船0.5分钟。假设原点与任意一个屋顶的连线不穿过其它屋顶。

· 输入格式:第一行,一个整数,表示屋顶数n。接下来依次有n行输入,每一行上包含两个表示屋顶相对于大本营的平面坐标位置的实数(单位是米)、一个表示人数的整数,数之间以一个空格分开。

· 输出格式:一行,救援需要的总时间,精确到分钟(向上取整)。

参考答案1 —— 基础版

#include <cmath> 
#include <iostream>
using namespace std;
int num;
int main(){
	cin >> num;
	int i = 1;
	double a = 0;
	double b = 0;
	double c = 0;
	double sumtime = 0;
	int renshu = 0;
	for (i = 1; i <= num; i++)
	{
		cin >> a >> b;
		c = sqrt(a * a + b * b);
		double time1 = c / 50 * 2;
		cin >> renshu;
		double time2 = renshu * 1.5;
		double time = time1 + time2;
		sumtime += time;
	}
	cout << (int)ceil(sumtime) << endl;
	return 0;
}

参考答案2 —— 优化版

#include <iostream>
#include <cmath>
using namespace std;
int n, p;
double x, y;
int main()
{
	cin >> n;
	double t = 0;
	for (int i = 0; i < n; i++)
	{
		cin >> x >> y >> p;
		float dis = sqrt(x * x + y * y);
		t += p * 1 + dis / 50 + p * 0.5 + dis / 50;
	}
	cout << (int)ceil(t) << endl;
	return 0;
}

本题注意点

1、本题当中应用到了简单的数学知识:直角三角形求斜边长度。

2、两个库函数 —— ceil函数和floor函数

(1)ceil函数 : 接收一个double类型的浮点数x作为参数,返回一个double类型的值。返回值是大于或等于x的最小整数。换句话说,ceil函数会将浮点数向上取整到最接近的整数,定义在头文件< cmath >中。

1)函数原型

double ceil(double x);

2)参数:x —— 需要进行向上取整的浮点数。

3)返回值:返回值是一个double类型的整数,表示大于或等于x的最小整数。

4)示例代码:

#include <cstdio>
#include <math.h>
int main(){
	double num1 = 3.14;
	double num2 = -3.14;
	double num3 = 5.0;
	double num4 = -5.0;
	printf("ceil(3.14) = %.0f\n", ceil(num1));  // 输出: 4
	printf("ceil(-3.14) = %.0f\n", ceil(num2)); // 输出: -3
	printf("ceil(5.0) = %.0f\n", ceil(num3));   // 输出: 5
	printf("ceil(-5.0) = %.0f\n", ceil(num4));  // 输出: -5
	return 0;
}

5)注意事项:ceil函数返回的是double类型,而不是int。虽然返回值是一个整数,但它仍然是浮点数形式。如果需要将其转换为int,需要进行强制类型转换。

(2)floor函数:接收一个double类型的浮点数x作为参数,返回一个double类型的值。返回值是小于或等于x的最大整数。即会将浮点数向下取整到最接近的整数,定义在头文件< cmath >中。

1)函数原型

double floor(double x);

2)参数:x —— 需要进行向下取整的浮点数。

3)返回值:返回值是一个double类型的整数,表示小于或等于x的最大整数。

4)示例代码:

#include <iostream>
#include <cmath>
int main() {
	double num1 = 3.14;
	double num2 = -3.14;
	double num3 = 5.0;
	double num4 = -5.0;
	std::cout << "floor(3.14) = " << floor(num1) << std::endl;  // 输出: 3
	std::cout << "floor(-3.14) = " << floor(num2) << std::endl; // 输出: -4
	std::cout << "floor(5.0) = " << floor(num3) << std::endl;   // 输出: 5
	std::cout << "floor(-5.0) = " << floor(num4) << std::endl;  // 输出: -5
	return 0;
}

练习五

        S_{n}=\frac{1}{1}-\frac{1}{2}+\frac{1}{3}-\frac{1}{4}+\frac{1}{5}-\frac{1}{6}\cdots,输入一个整数 n,求S_{n}

· 输入格式:输入为一行,含一个正整数 n。

· 输出格式:输出为一行,为 S_{n}的值,结果保留小数点后 4位小数。

· 说明/提示:1 ≤ n ≤ 1000。

参考答案1

#include <cstdio>
#include <iostream>
using namespace std;
int n;
int main(){
	cin >> n;
	double sum = 0;
	double a = 0;
	for (int i = 1; i <= n; i++)
{
		if (1 == i % 2)
			a = 1 * 1.0 / i;
		else
			a = (-1) * 1.0 / i;
		sum += a;
	}
	printf("%.4f", sum);
	return 0;
}

参考答案2

#include <iostream>
#include <iomanip>
using namespace std;
int n;
int main()
{
	cin >> n;
	int i = 0;
	float sum = 0;
	int flag = 1;
	for (i = 1; i <= n; i++)
	{
		sum += 1.0 / i * flag;
		flag = -flag;
	}
	cout << fixed << setprecision(4) << sum << endl;
	return 0;
}

练习六

参考输入输出

参考答案

#include <cstdio>
#include <iostream>
using namespace std;
int n;
int main()
{
	int p = 1;
	int q = 2;
	cin >> n;
	int i = 1;
	double sum = 0;
	for (i = 1; i <= n; i++)
	{
		sum += q * 1.0 / p;
		int ret = p;
		p = q;
		q = ret + q;
	}
	printf("%.4f", sum);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值