文章

【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读取整行并分割

  1. 处理输入:
    • 读取题目数量N
    • 使用getline读取每一行完整的转换表达式
    • 通过string的find函数找到空格、问号等关键位置
  2. 字符串处理:
    • 根据关键位置分割出数字、单位等信息
    • 使用substr提取大单位和小单位
    • 将字符串形式的数字转换为整数
  3. 单位转换:
    • 根据单位类型(km/kg、m/g)判断转换方式
    • 按照单位间的倍数关系计算结果
    • 输出符合格式要求的转换结果

方法二:直接使用cin按空格读取

  1. 输入处理:
    • 读取题目数量N
    • 利用cin自动按空格分割输入
    • 分别读取数字、单位、等号、问号等
  2. 单位转换:
    • 判断单位类型并进行相应计算
    • 处理千米到米/毫米、千克到克/毫克的转换
    • 处理米到毫米、克到毫克的转换
  3. 格式化输出:
    • 按照题目要求的格式拼接结果
    • 保持原始输入的空格和符号

复杂度分析:

  • 时间复杂度:$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-”系列题目可在编程启蒙题库进行在线评测。

本文由作者按照 CC BY 4.0 进行授权