口算练习题

GitHub跳转原题关系图返回列表

逐行解析运算类型,缺省类型时沿用上一题,再格式化表达式并输出长度。

OJ: luogu

题目 ID: P1957

难度:入门

标签:字符串模拟python

日期: 2026-07-15 20:30

题意

输入若干道口算题。每行可能有三个数据,也可能有两个数据。三个数据时第一个字符表示运算类型:a 加法、b 减法、c 乘法;两个数据时,运算类型沿用上一题。对每道题输出完整算式和这个算式字符串的长度。

思路

维护一个变量 current_operation 表示当前运算类型。

  • 如果当前行有三个 token,先更新 current_operation,再读取两个操作数。
  • 如果当前行有两个 token,直接沿用 current_operation

算出结果后,用 f-string 生成表达式,例如:

text
64+46=110

表达式长度就是 len(expression)

这题是按行解析和格式化输出练习,不创建 brute.py

Python 知识

  • /home/rainboy/mycode/hugo-blog/content/program_language/python/oj_input_output_cheatsheet.md:这类题要保留行结构,逐行 input().split() 更合适。
  • /home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.mdsplit() 按空白切分,len(parts) 可判断本行格式。
  • 字典 {"a": "+", "b": "-", "c": "*"} 可以把操作类型映射到输出符号。
  • f-string f"{left}{symbol}{right}={result}" 适合拼接带变量的算式。

代码

python
question_count = int(input())
current_operation = ""
symbols = {"a": "+", "b": "-", "c": "*"}

for _ in range(question_count):
    parts = input().split()
    if len(parts) == 3:
        current_operation = parts[0]
        left = int(parts[1])
        right = int(parts[2])
    else:
        left = int(parts[0])
        right = int(parts[1])

    symbol = symbols[current_operation]
    if current_operation == "a":
        result = left + right
    elif current_operation == "b":
        result = left - right
    else:
        result = left * right

    expression = f"{left}{symbol}{right}={result}"
    print(expression)
    print(len(expression))
cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-07-27 00:00
 * update_at: 2026-07-27 00:00
 */

#include <bits/stdc++.h>
using namespace std;

int n;             // 题目数量
char op;           // 当前运算类型 a/b/c
char line[1005];   // 每行输入

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int a, b;
        cin >> line; // 读取第一个 token
        if (line[0] >= 'a' && line[0] <= 'c') {
            op = line[0]; // 有运算符,更新当前类型
            cin >> a >> b;
        } else {
            sscanf(line, "%d", &a); // 第一个 token 是数字
            cin >> b;
        }

        int res;
        char sym;
        if (op == 'a') { res = a + b; sym = '+'; }
        else if (op == 'b') { res = a - b; sym = '-'; }
        else { res = a * b; sym = '*'; }

        // 计算表达式字符串的长度
        char expr[1005];
        sprintf(expr, "%d%c%d=%d", a, sym, b, res);
        cout << expr << "\n" << strlen(expr) << "\n";
    }
    return 0;
}

Pythonic 写法

operator 映射四则运算,统一生成表达式:

python
import operator

ops = {
    "a": ("+", operator.add),
    "b": ("-", operator.sub),
    "c": ("*", operator.mul),
}
current = ""

for _ in range(int(input())):
    parts = input().split()
    if len(parts) == 3:
        current, left, right = parts[0], int(parts[1]), int(parts[2])
    else:
        left, right = int(parts[0]), int(parts[1])
    symbol, func = ops[current]
    expression = f"{left}{symbol}{right}={func(left, right)}"
    print(expression)
    print(len(expression))

复杂度

设题目数为 i,每题只处理常数个 token,时间复杂度是 O(i)O(i),空间复杂度是 O(1)O(1)

总结

当输入行格式会省略字段时,用一个变量保存上一行状态,再按 token 数区分两种格式。