杭电oj第2061题:Treasure the new start, freshmen!
题目:
英文太多,我就直接翻译过来了。
新学期来临,HDU也迎来了50岁生日。不管你是什么专业,我唯一想告诉你的就是:“珍惜大学生活,抓紧时间。大多数人认为大学生活应该丰富多彩,少一些矫揉造作。但实际上,大学生活也是忙碌而坎坷的。如果你想掌握从书中学到的知识,应该把大量的闲暇时间花在个人学习和实践上,尤其是后者。我认为你们每个人都应该像在高中时一样采取学习的态度。
“不痛不收”,HDU也有奖学金,谁能拿得?这主要取决于学生的 GPA(平均绩点)。现在,我要告诉你规则,你的任务是编程以计算 GPA。
如果有 K(K > 0) 门课程,第 i 门课程有学分 Ci,你的分数 Si,那么结果 GPA 是
GPA = (C1 * S1 + C2 * S2 +......+Ci * Si......) / (C1 + C2 + ......+ Ci......)(1 <= i <= K, Ci != 0)
如果 0 <= Si < 60,则 GPA 始终不存在。
输入输出:
第一个数字 N 表示有 N 个测试用例 (N <= 50)。在每种情况下,都有一个数字 K(总课程
数),然后是 K 行,每行将遵循以下格式:课程名称(长度 <= 30)、学分(<= 10)、分数
(<= 100)。
注意:课程名称中没有空白。所有输入都是合法的输出上述每种情况的 GPA,如果 GPA 不存在,则输入:“对不起!”,否则只需输出四舍五入到小数点后 2 位数字的 GPA 值。两个测试用例之间有一条空行。
思路:
1、首先得得到输入输出。这就是为什么说C++来源C,又不同于C,你可以用C语言的scanf来输入课程名,学分,成绩。
2、浮点数的输出有两种,一种就是C语言的printf,或者C++的setprecision来控制浮点数位数。
代码:
#include <iostream>
#include <vector>
#include<iomanip>
using namespace std;
class student {
public:char name[31];float num;float score;
};int main() {int N;cin >> N;while (N--) {int n;cin >> n;vector<student> sum(n);bool flag = false;for (int i = 0; i < n; i++) {scanf("%s %f %f", sum[i].name, &sum[i].num, &sum[i].score);if (sum[i].score < 60)flag = true;}if (flag)cout << "Sorry!" << endl;else {float a = 0, b = 0;for (auto &m : sum) {a += m.score * m.num;b += m.num;}cout << fixed << setprecision(2) << a / b << endl;}}return 0;
}
补充知识:浮点数的位数控制
一、浮点数类型
float:单精度,约6到7的有效位数
double:双精度,约15到17的有效位数
long double:扩展精度,精度更高。
二、主要工具:<iomanip>
1、setprecision(n)
:设置有效数字位数(默认)或小数位数(配合fixed
)
2、fixed
:固定小数位数模式(与setprecision
配合使用)
3、scientific
:科学计数法模式
4、showpoint
:强制显示小数点和 trailing zeros
5、setw(n)
:设置输出宽度(不足补空格)
三、应用:
1、控制小数点位数:主要是fixed+setprecision(n)。n指的是位数
#include <iostream>
#include <iomanip>
using namespace std;int main() {double num = 3.1415926;// 保留2位小数cout << std::fixed << setprecision(2) << num << endl; // 输出 3.14// 保留4位小数cout << fixed << setprecision(4) << num << endl; // 输出 3.1416return 0;
}
2、控制有效位数,那就不需要fixed,直接用setprecision(n)。n是有效位数
#include <iostream>
#include <iomanip>
using namespace std;int main() {double num1 = 3.1415926535;double num2 = 0.00123456;double num3 = 12345.6789;// 保留3位有效数字cout << setprecision(3) << num1 << endl; // 输出 3.14cout << setprecision(3) << num2 << endl; // 输出 0.00123cout << setprecision(3) << num3 << endl; // 输出 1.23e+04(自动切换科学计数法)return 0;
}
3、科学计数法和普通格式切换
scientific:强制科学计数法
fixed:强制固定小数格式
defaultfloat:恢复默认格式
#include <iostream>
#include <iomanip>
using namespace std;int main() {double num = 123456.789;cout << "默认格式: " << num << std::endl; // 123457(默认精度6位)cout << "科学计数法: " << scientific << num << endl; // 1.234568e+05cout << "固定小数位: " << fixed << setprecision(2) << num << endl; // 123456.79cout << "恢复默认: " << defaultfloat << num << endl; // 123457return 0;
}
其实主要掌握前面两种:固定小数位数和有效位数。因为很多题都是让你输出多少位的小数,至于第三种,了解即可。