1 条题解

  • 0
    @ 2025-5-6 18:11:15

    题意分析

    给定只含变量 a ⁣ ⁣za\!-\!z、二元 ++/- 一元前置/后置 ++++/-- 的表达式,初始每个变量值分别为 1 ⁣ ⁣261\!-\!26。按照 C++ 的求值规则(所有前置自增先执行,再计算,中间结果不含 ++++/--,最后执行后置自增),求出表达式值及所有被用到变量的最终值。


    解题思路

    扫描表达式:遍历输入的字符数组,按遇到变量的先后顺序处理:

    • 若变量前有 ++++/--,则先修改变量值;
    • 根据前缀符号(默认首项视作有 “+” 前缀)取当前值累加或累减到 ansans
    • 若变量后有 ++++/--,则将其操作记录到后置操作队列,待主表达式计算完毕后再执行。

    后置操作:在主表达式计算后,按记录顺序更新对应变量。


    本题代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int maxn = 10010;
    int dataVals[26];          // 存储每个字母对应的数值
    enum { MAX_EXPR = maxn };
    char opr[maxn];            // 去除空格后的表达式
    char opr1[maxn];           // 原始输入表达式
    bool vst[26];              // 标记字母是否使用过
    
    void init() {
        for (int i = 0; i < 26; ++i) {
            dataVals[i] = i + 1;
            vst[i] = false;
        }
    }
    
    int main() {
        int T;
        if (scanf("%d", &T) != 1) return 0;
        getchar(); // 读取数字后的换行
        while (T--) {
            init();
            int ans = 0;
    
            // 读取一整行,包括可能的空格
            if (!fgets(opr1, MAX_EXPR, stdin)) break;
            // 去掉末尾的 '\n'
            size_t len1 = strlen(opr1);
            if (len1 > 0 && opr1[len1 - 1] == '\n') opr1[len1 - 1] = '\0';
    
            // 去除空格
            int j = 0;
            for (int i = 0; opr1[i] != '\0'; ++i) {
                if (opr1[i] != ' ') opr[j++] = opr1[i];
            }
            opr[j] = '\0';
    
            // 记录后置操作
            struct PostOp { int idx, delta; } postOps[maxn];
            int postCount = 0;
            char prevOp = '+';
            int n = j;
    
            for (int i = 0; i < n; ++i) {
                // 跳过前面可能的 ++/-- 标记,以便处理变量
                if (i + 1 < n && opr[i] == '+' && opr[i+1] == '+') { ++i; continue; }
                if (i + 1 < n && opr[i] == '-' && opr[i+1] == '-') { ++i; continue; }
    
                if (opr[i] >= 'a' && opr[i] <= 'z') {
                    int idx = opr[i] - 'a';
                    vst[idx] = true;
                    // 前置 ++/--
                    if (i - 2 >= 0 && opr[i-2] == '+' && opr[i-1] == '+') {
                        dataVals[idx] += 1;
                    } else if (i - 2 >= 0 && opr[i-2] == '-' && opr[i-1] == '-') {
                        dataVals[idx] -= 1;
                    }
                    int val = dataVals[idx];
                    // 累加或累减
                    if (prevOp == '+') ans += val;
                    else                ans -= val;
                    // 后置 ++/--
                    if (i + 2 < n && opr[i+1] == '+' && opr[i+2] == '+') {
                        postOps[postCount++] = { idx, +1 };
                    } else if (i + 2 < n && opr[i+1] == '-' && opr[i+2] == '-') {
                        postOps[postCount++] = { idx, -1 };
                    }
                    // 更新 prevOp
                    for (int k = i+1; k < n; ++k) {
                        if (opr[k] == '+' || opr[k] == '-') {
                            prevOp = opr[k]; break;
                        }
                    }
                }
            }
    
            // 执行后置操作
            for (int i = 0; i < postCount; ++i) {
                dataVals[postOps[i].idx] += postOps[i].delta;
            }
    
            // 输出结果
            printf("Expression: %s\n", opr1);
            printf("value = %d\n", ans);
            for (int i = 0; i < 26; ++i) {
                if (vst[i]) {
                    printf("%c = %d\n", char('a' + i), dataVals[i]);
                }
            }
        }
        return 0;
    }
    
    
    
    • 1

    信息

    ID
    2338
    时间
    2000ms
    内存
    64MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者