




第三部分编程题 第二题
《健康王国------BMI 排名大赛》
第一幕:健康王国举办比赛
1、有一天,健康王国举办了一场比赛。
来了很多小朋友。
(1)老师记录了他们的信息:
编号
体重
身高
(2)例如:
| 编号 | 体重 | 身高 |
|---|---|---|
| 1 | 45kg | 1.55m |
| 2 | 33kg | 1.33m |
| 3 | 39kg | 1.44m |
(3)老师说:
今天不是比谁最高,
也不是比谁最重,
而是比较 BMI(身高体重指数)!
第二幕:什么是BMI?
1、BMI计算公式:
BMI = 体重 ÷ 身高²
2、分别计算每一位同学:
(1)第一位同学:
45kg
1.55m
计算:
45 ÷ 1.55 ÷ 1.55
约等于:
18.73
(2)第二位同学:
33
1.33
得到:
18.66
(3)第三位同学:
39
1.44
得到:
18.81
3、排序:
3号 > 1号 > 2号
输出:
3 1 2
这就是样例。
第三幕:计算机怎样保存这些数据?
1、这里用到了
结构体。
2、定义结构体
struct Human
{
int id;
int w;
double h;
};
3、意思:
一个Human里面,
已经装好了:
编号
体重
身高
这就像一个学生档案袋。
第四幕:建立档案袋
1、于是:
Human humans[1000];
表示:
1000个档案袋
2、例如:
humans[0]
↓
编号1
体重45
身高1.55
3、第二个人:
humans[1]
↓
编号2
体重33
身高1.33
是不是一下整齐了?
第五幕:比较两个人的bmi:
1、第一位:
double bmi1 =
humans[i].w /
humans[i].h /
humans[i].h;
2、第二位:
double bmi2 =
humans[j].w /
humans[j].h /
humans[j].h;
3、然后:
比较:
bmi1 和 bmi2
第六幕:如何排序?
1、同学看到:
排序
第一反应:
就应该是sort,省码代码的时间!
2、当然也可以手写排序:
比如:
冒泡排序
第七幕:完整流程图
写程序前,先手写流程图。
开始
│
▼
输入人数n
│
▼
输入所有体重
│
▼
输入所有身高
│
▼
编号1~n
│
▼
排序
│
▼
比较BMI
│
▼
BMI大的放前面
│
▼
交换整个结构体
│
▼
输出编号
│
▼
结束
这就是整道题的思路。
第八幕:不要忘记先编号?
1、注意:
输入:
45
33
39
没有编号。
怎么办?
2、按照输入顺序:
第一个
↓
1号
第二个:
↓
2号
第三个:
↓
3号
3、于是:
humans[i].id=i+1;
以后:
排序结束。
输出:
id
即可。
第九幕:完整代码
1、冒泡排序
#include <iostream>
using namespace std;
struct Human
{
int id; // 编号
int w; // 体重
double h; // 身高
};
Human humans[1010];
int main()
{
int n;
cin >> n;
// 编号
for(int i=0;i<n;i++)
humans[i].id=i+1;
// 输入体重
for(int i=0;i<n;i++)
cin>>humans[i].w;
// 输入身高
for(int i=0;i<n;i++)
cin>>humans[i].h;
// 冒泡排序
for(int i=0;i<n;i++)
{
for(int j=0;j<n-1-i;j++)
{
double bmi1=(double)humans[j].w/
humans[j].h/
humans[j].h;
double bmi2=(double)humans[j+1].w/
humans[j+1].h/
humans[j+1].h;
if(bmi1<bmi2)
swap(humans[j],humans[j+1]);
}
}
// 输出编号
for(int i=0;i<n;i++)
cout<<humans[i].id<<" ";
cout<<endl;
return 0;
}
2、sort排序
cpp
#include <iostream>
#include <algorithm> // 必须包含此头文件以使用 sort
using namespace std;
struct Human
{
int id; // 编号
int w; // 体重
double h; // 身高
};
Human humans[1010];
// 手写比较函数 cmp
// 规则:按照 BMI 从大到小排序(降序)
bool cmp(const Human& a, const Human& b)
{
// 计算 a 的 BMI: weight / (height * height)
double bmi_a = (double)a.w / (a.h * a.h);
// 计算 b 的 BMI
double bmi_b = (double)b.w / (b.h * b.h);
// 如果 a 的 BMI 大于 b 的 BMI,则 a 排在 b 前面
return bmi_a > bmi_b;
}
int main()
{
int n;
cin >> n;
// 编号
for(int i = 0; i < n; i++)
humans[i].id = i + 1;
// 输入体重
for(int i = 0; i < n; i++)
cin >> humans[i].w;
// 输入身高
for(int i = 0; i < n; i++)
cin >> humans[i].h;
// 使用 std::sort 进行排序
// 第三个参数传入手写函数名 cmp
sort(humans, humans + n, cmp);
// 输出编号
for(int i = 0; i < n; i++)
cout << humans[i].id << " ";
cout << endl;
return 0;
}
第十幕:这道题真正考察什么?
这道题考察的是:
第一层:结构体
学会把多个相关数据放进一个对象里,而不是分散在多个数组中。
第二层:结构体排序
比较的是根据公式实时计算出的BMI值。
第三层:交换整个对象
排序时,不是交换体重,也不是交换身高,而是交换整个学生信息。
第四层:自定义比较
cpp
bool cmp(const Human& a, const Human& b)
{
// 计算 a 的 BMI: weight / (height * height)
double bmi_a = (double)a.w / (a.h * a.h);
// 计算 b 的 BMI
double bmi_b = (double)b.w / (b.h * b.h);
// 如果 a 的 BMI 大于 b 的 BMI,则 a 排在 b 前面
return bmi_a > bmi_b;
}
最后送给同学们一首《BMI排序口诀》
一个学生一个包(结构体),
编号体重身高装。
BMI不用提前放,
比较时候现场算。
大的前,小的后,
交换整个档案包。
最后输出编号去,
结构体排序就学会了!
汉克老师提醒:
每次四级考试100%都会有一道题目,用到排序算法。
1、冒泡排序、选择排序、插入排序的基本模版必须要掌握。
2、sort是四级学生编程题中使用最方便的排序方法,要熟练掌握。
3、考试的难点是,在于把多个知识点融合在一起,如本题:
结构体:把编号、体重、身高封装成一个整体。
浮点数运算 :正确计算 BMI(注意使用
double)。自定义排序规则:不是直接比较数组元素,而是比较计算得到的 BMI。
交换整个结构体:保持编号、体重、身高始终对应。