全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之循环结构(应用)
实战训练1—球弹跳高度的计算
问题描述:
一球从某一高度h落下(单位米),每次落地后反弹回原来高度的一半,再落下。编程计算球在第10次落地时,共经过多少米? 第10次反弹多高?
输入格式:
输入一行一个整数h,表示球的初始高度。
输出格式:
输出两行每行一个数,第1行:球第10次落地时,一共经过的米数;第2行:第10次弹跳的高度。
输入输出样例:
输入样例1 | 输出样例1 |
10 | 29.9609 0.00976562 |
输出样例1 | 输出样例2 |
20 | 59.9219 0.0195312 |
问题分析:
根据题意,球从某一高度 h 落下,每次落地后反弹回原来高度的一半,需要计算球在第10次落地时,总共经过的距离以及第10次反弹的高度。本题使用循环来模拟球的落下和反弹过程,直到第10次落地,每次落下和反弹时,累加球经过的距离,更新反弹高度为当前高度的一半,具体程序代码如下:
#include<bits/stdc++.h>
using namespace std;
int main() {
int h;//定义求的起始高度变量h
cin>>h;//输入h的值
double sum=0,tmp=h;//定义变量sum表示球一共经过了多少米,tmp表示每次球可以反弹的高度
for(int i=1; i<=10; i++) {
sum+=tmp;//首先将落下的高度累加到sum中
tmp=tmp*1.0/2;//球可以反弹的高度
sum+=tmp;//将上升的高度累加到sum中
if(tmp==0.0)//如果反弹高度为0
break;//跳出循环
}
cout<<sum-tmp<<endl;//输出落地时总共经过的米数
cout<<tmp<<endl;//输出反弹高度
return 0;
}
实战训练2—分苹果
问题描述:
把一堆苹果分给n个小朋友,要使每个人都能拿到苹果,而且每个人拿到的苹果数都不同的话,这堆苹果至少应该有多少个?
输入格式:
输入一行一个整数n,表示小朋友的人数。
输出格式:
输出一行一个整数,表示满足条件的最少苹果个数。
输入输出样例:
输入样例1 | 输出样例1 |
10 | 55 |
输出样例1 | 输出样例2 |
20 | 210 |
问题分析:
根据题意,每个小朋友都要拿到苹果,即没有小朋友是空的,每个小朋友拿到的苹果数量不同,即不存在两个小朋友拿到相同数量的苹果;为了满足上述条件,可以构建一个递增的整数序列,其中每个数字代表一个小朋友拿到的苹果数量,这个序列从1开始,因为最小的正整数是1,并且每个小朋友至少拿到一个苹果;序列中的数字之和就是所需的最少苹果数量,对于n个小朋友,序列将是1, 2, 3, ..., n,最终转换成使用循环求1到n这个n个数的和,具体程序代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,sum=0;//定义两个变量小朋友人数n和苹果总数sum并初始化为0
cin>>n;//输入小朋友的人数
for(int i=1;i<=n;i++){//循环变量从1开始到n结束
sum+=i;//将i累加到sum中
}
cout<<sum<<endl;//输出所需的苹果个数
return 0;
}
实战训练3—正常血压
问题描述:
监护室每小时测量一次病人的血压,若收缩压在90∼140 之间并且舒张压在60∼90 之间(包含端点值)则称之为正常,现给出某病人若干次测量的血压值,计算病人保持正常血压的最长小时数。
输入格式:
输入共n+1行,第一行为一个正整数n(n<100),表示病人测量的血压次数,其后有n行,每行2个正整数,分别为一次测量的收缩压和舒张压。
输出格式:
输出一行一个整数,表示血压连续正常的最长小时数。
输入输出样例:
输入样例1 | 输出样例1 |
10 | 55 |
输出样例1 | 输出样例2 |
20 | 210 |
问题分析:
根据题意,需要解决的问题是:给定一系列血压测量值(每个测量值包含收缩压和舒张压),计算病人在连续测量中保持正常血压的最长小时数。正常血压的定义是:收缩压在90到140之间(包含90和140),舒张压在60到90之间(包含60和90),需要遍历所有的血压测量值,并检查每个连续的血压测量值是否都在正常范围内。如果是,则计数器增加;如果不是,则重置计数器,并继续检查后续的测量值。实现步骤为:初始化一个计数器 maxv为0,用于记录最长保持正常血压的小时数,并初始化一个计数器 t为0,用于记录当前连续保持正常血压的小时数;然后使用循环遍历所有的血压测量值:如果当前测量值是正常血压,则 t增加1;如果当前测量值不是正常血压,则更新 maxv为 maxv和 t中的较大值,并重置 t为0;遍历结束后,再次更新 maxv为 maxv和 t中的较大值(处理最后一段连续正常血压的情况);最后输出 maxv。具体程序代码如下:
#include<bits/stdc++.h>
using namespace std;
int main() {
int n,maxv=0,t=0;//定义测量血压的次数变量n,以及记录最长保持正常血压的小时数maxv和 当前连续保持正常血压的小时数t
cin>>n;//输入n的值
int i=1;//定义循环变量i初始化为1
while(i<=n){//只要血压测量次数小于等于n
int t1,t2;//定义收缩压变量t1和缩张压变量t2
cin>>t1>>t2;//输入t1和t2变量
if((t1>=90 && t1<=140)&& (t2>=60 && t2<=90)) {//判断t1和t2时候在正常范围内
t++;//则计数器增加
} else {
t=0;//重置计数器
}
if(t>maxv) {//判断t的值是否大于maxv
maxv=t;//更新maxv
}
i++;//循环变量自增运算
}
if(t>maxv){//判断最后一次正常血压的保持时间是否大于maxv
maxv = t;
}
cout<<maxv<<endl;//输出maxv的值
return 0;
}