【GESP】C++三级真题 luogu-B3926 [GESP202312 三级] 单位转换
GESP三级真题,字符串相关题目,难度★★☆☆☆。
luogu-B3926 [GESP202312 三级] 单位转换
题目要求
题目描述
小杨这周的数学作业是做单位转换,喜欢编程的小杨决定编程帮他解决这些问题。
小杨只学了长度单位和重量单位,具体来说:
长度单位包括千米(
km
)、米(m
)、毫米(mm
),它们之间的关系是:$1\text{km} = 1000\text{m} = 1000000\text{mm}$。重量单位包括千克(
kg
)、克(g
)、毫克(mg
),它们之间的关系是:$1\text{kg} = 1000\text{g} = 1000000\text{mg}$。小杨的作业只涉及将更大的单位转换为更小的单位,也就是说,小杨的作业只会包含如下题型:米转换为毫米,千米转换为毫米,千米转换为米,克转换为毫克,千克转换为毫克,千克转换为克。
现在,请你帮忙完成单位转换的程序。
输入格式
输入的第一行为一个整数,表示题目数量。
接下来 $N$ 行,每行一个字符串,表示转换单位的题目,格式为 $x$ 单位 $1 = ?$ 单位 $2$。其中,$x$ 为一个不超过 $1000$ 的非负整数, 单位 $1$ 和 单位 $2$ 分别为两个单位的英文缩写,保证它们都是长度单位或都是重量单位,且 单位 1 比 单位 2 更大。
例如,如果题目需要你将 $1\text{km}$ 转换为 $\text{mm}$,则输入为
1 km = ? mm
。保证 $1\le N \le 1000$。
输出格式
输出 $N$ 行,依次输出所有题目的答案,输出时,只需要将输入中的 $?$ 代入答案,其余部分一字不差地输出即可。由于小杨的题目只涉及将更大的单位转换为更小的单位,并且输入的 $x$ 是整数,因此答案一定也是整数。
例如,如果题目需要你将 $1\text{km}$ 转换为 $\text{mm}$,则输入为
1 km = ? mm
。则你需要输出1 km = 1000000 mm
。
输入输出样例 #1
输入 #1
1
2
3
2
1 km = ? mm
1 m = ? mm
输出 #1
1
2
1 km = 1000000 mm
1 m = 1000 mm
输入输出样例 #2
输入 #2
1
2
3
4
5
6
5
100 m = ? mm
1000 km = ? m
20 kg = ? g
200 g = ? mg
0 kg = ? mg
输出 #2
1
2
3
4
5
100 m = 100000 mm
1000 km = 1000000 m
20 kg = 20000 g
200 g = 200000 mg
0 kg = 0 mg
题目分析
解题思路
本题可以采用两种解题思路:
方法一:使用getline读取整行并分割
- 处理输入:
- 读取题目数量N
- 使用getline读取每一行完整的转换表达式
- 通过string的find函数找到空格、问号等关键位置
- 字符串处理:
- 根据关键位置分割出数字、单位等信息
- 使用substr提取大单位和小单位
- 将字符串形式的数字转换为整数
- 单位转换:
- 根据单位类型(km/kg、m/g)判断转换方式
- 按照单位间的倍数关系计算结果
- 输出符合格式要求的转换结果
方法二:直接使用cin按空格读取
- 输入处理:
- 读取题目数量N
- 利用cin自动按空格分割输入
- 分别读取数字、单位、等号、问号等
- 单位转换:
- 判断单位类型并进行相应计算
- 处理千米到米/毫米、千克到克/毫克的转换
- 处理米到毫米、克到毫克的转换
- 格式化输出:
- 按照题目要求的格式拼接结果
- 保持原始输入的空格和符号
复杂度分析:
- 时间复杂度:$O(N)$,N为题目数量
- 空间复杂度:$O(1)$,仅使用常数级别额外空间
示例代码
方法一 整行读入,利用字符串查找函数find进行分割
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <string>
int main() {
// 读取题目数量
int n;
std::cin >> n;
// 清除输入缓冲区中的换行符,避免影响后续的getline读取
std::cin.ignore();
// 循环处理每个转换题目
for (int i = 0; i < n; i++) {
std::string str;
// 读取一整行输入
getline(std::cin, str);
// 查找关键位置索引
std::size_t first_blank_idx = str.find(" "); // 第一个空格位置
std::size_t second_blank_idx = str.find(" ", first_blank_idx + 1); // 第二个空格位置
std::size_t question_idx = str.find("?"); // 问号位置
// 提取单位信息
std::string big_unit = str.substr(
first_blank_idx + 1, second_blank_idx - first_blank_idx - 1); // 大单位
std::string small_unit =
str.substr(question_idx + 2, str.length() - question_idx - 2); // 小单位
// 提取数值并转换为整数
int first_num = std::stoi(str.substr(0, first_blank_idx));
int second_num;
// 根据单位类型进行转换计算
if (big_unit == "km" || big_unit == "kg") {
if (small_unit == "m" || small_unit == "g") {
second_num = first_num * 1000; // 千米转米或千克转克
} else if (small_unit == "mm" || small_unit == "mg") {
second_num = first_num * 1000 * 1000; // 千米转毫米或千克转毫克
}
} else if (big_unit == "m" || big_unit == "g") {
second_num = first_num * 1000; // 米转毫米或克转毫克
}
// 按格式输出结果
std::cout << first_num << " " << big_unit << " " << "=" << " "
<< second_num << " " << small_unit << std::endl;
}
return 0;
}
方法二,直接用cin读取,自动按空格分成5段,更简单
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <string>
int main() {
// 读取题目数量
int n;
std::cin >> n;
while (n--) {
// 定义变量存储输入数据
int f_n, s_n; // f_n: 第一个数字, s_n: 转换后的数字
std::string b_u, eq, s_u, q; // b_u: 大单位, eq: 等号, s_u: 小单位, q: 问号
// 读取一行输入数据
std::cin >> f_n >> b_u >> eq >> q >> s_u;
// 根据单位进行转换计算
if (b_u == "km" || b_u == "kg") { // 如果是千米或千克
if (s_u == "m" || s_u == "g") { // 转换为米或克
s_n = f_n * 1000;
} else { // 转换为毫米或毫克
s_n = f_n * 1000 * 1000;
}
} else { // 如果是米或克,转换为毫米或毫克
s_n = f_n * 1000;
}
// 按格式输出结果
std::cout << f_n << " " << b_u << " " << "=" << " " << s_n << " " << s_u
<< std::endl;
}
}
所有代码已上传至Github:https://github.com/lihongzheshuai/yummy-code
GESP各级别考纲要点、知识拓展和练习题目清单详见C++学习项目主页
“luogu-”系列题目已加入洛谷Java、C++初学团队,作业清单,可在线评测,团队名额有限,欢迎加入。
“bcqm-”系列题目可在编程启蒙题库进行在线评测。