2090.算菜价
题目描述
Problem - 2090
Problem Description
妈妈每天都要出去买菜,但是回来后,兜里的钱也懒得数一数,到底花了多少钱真是一笔糊涂帐。现在好了,作为好儿子(女儿)的你可以给她用程序算一下了,呵呵。
Input
输入含有一些数据组,每组数据包括菜种(字串),数量(计量单位不论,一律为double型数)和单价(double型数,表示人民币元数),因此,每组数据的菜价就是数量乘上单价啊。菜种、数量和单价之间都有空格隔开的。
Output
支付菜价的时候,由于最小支付单位是角,所以总是在支付的时候采用四舍五入的方法把分头去掉。最后,请输出一个精度为角的菜价总量。
运行代码
#include <iostream>
#include<string>
using namespace std;
int main() {string name;double n, m, sum = 0.0;while (cin >> name >> n >> m)sum += n* m;printf("%.1f\n", sum);return 0;
}
代码思路
- 引入所需头文件:
<iostream>
用于实现输入输出功能,<string>
用于使用字符串类型。 - 声明命名空间
std
,这样就可以在代码中直接使用标准库中的函数和对象,而不需要每次都加前缀std::
。 - 定义主函数
int main()
,这是C++程序的入口点。 - 在主函数内声明变量:
string name;
用于存储菜的名字。double n, m, sum = 0.0;
定义了三个双精度浮点数变量,其中n
和m
分别表示菜的数量以及单价,sum
初始化为0,用于累计所有菜的价格。
- 使用
while (cin >> name >> n >> m)
循环读取输入:- 这里使用了C++的输入流
cin
从标准输入(通常是键盘)读取数据。每次循环都会尝试读取一个菜名(字符串)、一个数量(double类型)和一个单价(double类型)。当读取成功时,循环继续;如果遇到输入结束(如文件尾或用户中断),则循环终止。 - 在循环体内,菜的价格累加,数量乘以单价。
- 这里使用了C++的输入流
- 循环结束后,使用
printf("%.1f\n", sum);
输出累计的菜价,格式化字符串"%.1f"
指定输出一个浮点数,并保留一位小数。 return 0;
表示程序正常结束,返回值0通常表示成功执行。
2091.空心三角形
题目描述
Problem - 2091
Problem Description
把一个字符三角形掏空,就能节省材料成本,减轻重量,但关键是为了追求另一种视觉效果。在设计的过程中,需要给出各种花纹的材料和大小尺寸的三角形样板,通过电脑临时做出来,以便看看效果。
Input
每行包含一个字符和一个整数n(0<n<41),不同的字符表示不同的花纹,整数n表示等腰三角形的高。显然其底边长为2n-1。如果遇到@字符,则表示所做出来的样板三角形已经够了。
Output
每个样板三角形之间应空上一行,三角形的中间为空。显然行末没有多余的空格。
运行代码
#include<iostream>
#include<string>
using namespace std;
void print(char str, int n) {for (int i = 1; i <= n; i++) {for (int j = 1; j <= n - i; j++)cout << " ";if (i != n) {for (int j = 1; j <= 2 * i - 1; j++) {if (j == 1 || j == 2 * i - 1)cout << str;else cout << " ";}}else {for (int j = 1; j <= 2 * i - 1; j++)cout << str;}cout << endl;}
}
int main() {char str;int n;bool s = false;while (cin >> str) {if (str == '@') break;cin >> n;print(str, n);s = true;}return 0;
}
代码思路
-
包含头文件:首先,代码通过
#include
指令包含了iostream
和string
两个标准库,分别用于处理输入输出和字符串操作。 -
命名空间使用:
using namespace std;
这一行是为了避免在使用标准库中的功能时频繁地写出std::
前缀。 -
print函数定义:
- 函数接收两个参数:一个字符
str
用于构建金字塔,一个整数n
表示金字塔的高度。 - 使用两层嵌套循环来控制每一层的打印。外层循环变量
i
控制行数(从1到n),内层循环分别控制每行的空格和字符打印。 - 首先打印每行开始的空格,数量由
n - i
决定,以保证金字塔的形状。 - 接着,判断是否为金字塔的最后一行(即
i == n
),如果是,则该行全部打印字符str
;否则,按照金字塔形状打印字符和空格。首尾字符一定是str
,中间用空格填充。 - 每完成一行的打印后,输出换行符
endl
。
- 函数接收两个参数:一个字符
-
main函数逻辑:
- 初始化一个布尔变量
s
为false
,用来标记是否有有效输入。 - 使用一个
while
循环持续读取用户输入,直到遇到字符'@'为止。 - 在循环中,首先读取一个字符,然后读取一个整数,这两个值分别赋给
str
和n
。 - 调用
print
函数,传入读取到的字符和高度,打印相应的金字塔图案。 - 设置
s
为true
,表示至少有一次有效输入。 - 当用户输入'@'结束循环后,程序返回0,正常终止。
- 初始化一个布尔变量
2093.考试排名
题目描述
Problem - 2093
Problem Description
C++编程考试使用的实时提交系统,具有即时获得成绩排名的特点。它的功能是怎么实现的呢?
我们做好了题目的解答,提交之后,要么“AC”,要么错误,不管怎样错法,总是给你记上一笔,表明你曾经有过一次错误提交,因而当你一旦提交该题“AC”后,就要与你算一算帐了,总共该题错误提交了几回。虽然你在题数上,大步地跃上了一个台阶,但是在耗时上要摊上你共花去的时间。特别是,曾经有过的错误提交,每次都要摊上一定的单位时间分。这样一来,你在做出的题数上,可能领先别人很多,但是,在做出同样题数的人群中,你可能会在耗时上处于排名的劣势。
例如:某次考试一共8题(A,B,C,D,E,F,G,H),每个人做的题都在对应的题号下有个数量标记,负数表示该学生在该题上有过的错误提交次数,但到现在还没有AC,正数表示AC所耗的时间,如果正数a跟上一对括号,里面有个整数b,那就表示该学生提交该题AC了,耗去了时间a,同时,曾经错误提交了b次,因此对于下述输入数据:
若每次错误提交的罚分为20分,则其排名从高到低应该是这样的:
Josephus 5 376
John 4 284
Alice 4 352
Smith 3 167
Bob 2 325
Bush 0 0
Input
输入数据的第一行是考试题数n(1≤n≤12)以及单位罚分数m(10≤m≤20),每行数据描述一个学生的用户名(不多于10个字符的字串)以及对所有n道题的答题现状,其描述采用问题描述中的数量标记的格式,见上面的表格,提交次数总是小于100,AC所耗时间总是小于1000。
Output
将这些学生的考试现状,输出一个实时排名。实时排名显然先按AC题数的多少排,多的在前,再按时间分的多少排,少的在前,如果凑巧前两者都相等,则按名字的字典序排,小的在前。每个学生占一行,输出名字(10个字符宽),做出的题数(2个字符宽,右对齐)和时间分(4个字符宽,右对齐)。名字、题数和时间分相互之间有一个空格。
运行代码
#include<iostream>
#include<string>
#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
struct student {string name;int num;int time;
};
bool compare(student a, student b) {if (a.num == b.num && a.time == b.time)return a.name < b.name;elseif (a.num == b.num)return a.time < b.time;elsereturn a.num > b.num;
}
int main()
{student stu[10005];int n, m, numstu = 0;cin >> n >> m;string s;getchar();while (cin >> s) {int k = 10 - s.length();while (k--)s.append(" ");stu[numstu].name = s;stu[numstu].num = 0;stu[numstu].time = 0;int num = n;while (num--) {string score;cin >> score;if (score.find('-') != -1 || score.compare("0") == 0)continue;stu[numstu].num++;int time = 0;int fatime = 0;for (int i = 0; i < score.length(); i++) {if (score[i] >= '0' && score[i] <= '9')time = time * 10 + score[i] - 48;if (score[i] == '(') {for (int j = i + 1; j < score.length() - 1; j++) {fatime = fatime * 10 + score[j] - 48;}break;}}stu[numstu].time += time + fatime * m;}numstu++;}sort(stu, stu + numstu, compare);for (int i = 0; i < numstu; i++) {cout << stu[i].name << " ";if (stu[i].num < 10)cout << " ";cout << stu[i].num << " ";if (stu[i].time < 10)cout << " ";else if (stu[i].time < 100)cout << " ";else if (stu[i].time < 1000)cout << " ";cout << stu[i].time << endl;}return 0;
}
代码思路
- 定义了一个
student
结构体来表示学生的信息,包括姓名、答题数量和答题总时间。 compare
函数用于定义结构体比较的规则,先按照答题数量降序排序,数量相同则按答题时间升序排序,再相同则按姓名字典序排序。- 在
main
函数中:- 首先读取题目数量
n
和每题分值m
。 - 通过循环不断读取学生姓名,并初始化该学生的结构体信息。
- 然后对于每个学生,再读取
n
个答题情况。如果答题情况不是-
或0
,则增加答题数量,并从答题情况中解析出答题时间和额外时间,计算并累加到该学生的总时间。 - 所有学生信息读取处理完后,使用自定义的比较函数对学生结构体数组进行排序。
- 最后遍历排序后的数组,按照特定格式输出每个学生的姓名、答题数量和答题总时间。
- 首先读取题目数量