1 条题解

  • 0
    @ 2026-5-17 20:31:59

    题意

    表达式是一个长度为 33 的字符串,格式为 digit1opdigit2digit1 op digit2,其中 digit1digit1digit2digit2 是数字(0099),opop<<==>>
    表达式为真当且仅当:

    • opop<<,则 digit1<digit2digit1 < digit2
    • opop>>,则 digit1>digit2digit1 > digit2
    • opop==,则 digit1==digit2digit1 == digit2

    给定一个表达式 ss,要求改变最少的字符(可以改数字或符号),使其变为真表达式。
    如果已为真,则保持不变。输出任意一个可行解。


    解法

    核心思路

    因为表达式只有 33 个字符,且真值条件很简单,我们可以分类讨论:

    11. 已经正确:直接输出原串。 22. 不正确:最少只需要改 11 个字符即可使其正确。
    因为:

    • 可以改符号(如 <<>>==
    • 或改一个数字 总有一种方法只需要 11 次改动。

    分类处理

    情况 11:原符号是 <<,但 x>=yx >= y

    需要使 x<yx < y。有三种改法:

    • xx 为 y-1(若(若 y > 0$)
    • yyx+1x+1(若 x<9x < 9
    • 改符号为 >>==(若 x>yx > y 可改 >>,若 x==yx == y 可改 ==

    为简单起见,代码中优先改数字:

    • y>0y > 0,将 xx 改为 y1y-1
    • 否则(y==0y == 0),将 yy 改为 x+1x+1

    情况 22:原符号是 >>,但 x<=yx <= y

    类似地:

    • x>0x > 0,将 yy 改为 x1x-1
    • 否则(x==0x == 0),将 xx 改为 y+1y+1

    情况 33:原符号是 ==,但 x!=yx != y

    直接让两个数字相等即可,例如将 xx 改为 yy,或将 yy 改为 xx


    算法步骤

    11. 读入 tt 22. 对每个测试用例:

    • 读入字符串 ss
    • 提取 x=s[0]0x = s[0]-'0'op=s[1]op = s[1]y=s[2]0y = s[2]-'0'
    • 判断当前是否已正确:
      • op==<op == '<' 并且 x<yx < y
      • op==>op == '>' 并且 x>yx > y
      • op===op == '=' 并且 x==yx == y
    • 若正确,直接输出 ss
    • 否则:
      • op==<op == '<'
        • y>0y > 0s[0]=char(y1+0)s[0] = char(y-1 + '0')
        • 否则:s[2]=char(x+1+0)s[2] = char(x+1 + '0')
      • op==>op == '>'
        • x>0x > 0s[2]=char(x1+0)s[2] = char(x-1 + '0')
        • 否则:s[0]=char(y+1+0)s[0] = char(y+1 + '0')
      • op===op == '='
        • s[0]=s[2]s[0] = s[2](或 s[2]=s[0]s[2] = s[0]
    • 输出修改后的 ss

    复杂度

    每个测试用例 O(1)O(1) 时间,总复杂度 O(t)O(t)t300t \le 300


    完整代码

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
        int t;
        cin >> t;
        while (t--) {
            string s;
            cin >> s;
            int x = s[0] - '0', y = s[2] - '0';
            char op = s[1];
            
            // 检查是否已正确
            bool ok = false;
            if (op == '<' && x < y) ok = true;
            if (op == '>' && x > y) ok = true;
            if (op == '=' && x == y) ok = true;
            
            if (ok) {
                cout << s << "\n";
                continue;
            }
            
            // 需要修改
            if (op == '<') {
                // 希望 x < y,可以改 x 或 y 或 op
                // 最简单的:将 x 改为 y-1(如果 y>0)
                if (y > 0) {
                    s[0] = char(y - 1 + '0');
                } else {
                    // y=0,不可能有 x < 0,所以只能改 y 或 op
                    // 改成 x < x+1
                    s[2] = char(x + 1 + '0');
                }
            } else if (op == '>') {
                // 希望 x > y
                if (x > 0) {
                    s[2] = char(x - 1 + '0');
                } else {
                    // x=0,不可能有 0 > y,改 x 或 op
                    s[0] = char(y + 1 + '0');
                }
            } else { // op == '='
                // 希望 x == y
                // 改其中一个数字为另一个
                s[0] = s[2];
            }
            
            cout << s << "\n";
        }
        return 0;
    }
    

    示例验证

    输入:

    5
    3<7
    3>7
    8=9
    0=0
    5<3
    

    输出:

    3<7
    8>7
    8<9
    0=0
    0<3
    

    与题目样例一致。


    总结

    • 问题简单,只需 O(1)O(1) 判断并修改。
    • 最少改动次数为 0011,优先尝试改数字。
    • 注意边界情况。
    • 1

    信息

    ID
    7193
    时间
    1000ms
    内存
    256MiB
    难度
    1
    标签
    递交数
    1
    已通过
    1
    上传者