P1022 [NOIP2000 普及组] 计算器的改良

题解


题目链接

P1022 [NOIP2000 普及组] 计算器的改良

题目大意

给定一个合法有解的一元一次方程,其中只包含整数系数以及 +, -, =, 求该方程的解。
如:

  • \(6a−5+1=2−2a\)
  • \(−5+y=2y+6\)

等。

解题思路

模拟
按正常解方程思路来模拟,可以将原方程化简成 \(ax=b\) 的形式,则可得方程解 \(x=b/a\)
模拟过程中按各个数字是未知数前的系数 \(a\) 还是常数项 \(b\) 统计即可。

时间复杂度与空间复杂度分析

很显然,线性的模拟,时间与空间复杂度均为 \(O(n)\)

完整代码

#include <bits/stdc++.h>

using namespace std;

int main() {
    string s;
    cin >> s;
    for (int i = 0; i < s.size(); ++i) {
        if (isalpha(s[i]) && (!i || !isdigit(s[i - 1]))) {
            s = s.substr(0, i) + '1' + s.substr(i);     //提前预处理...+x或...-x(即未知数系数为±1)的情况,避免特判
        }                                               //其实也可在下面isalpha处处理
    }
    s += '#';  //在字符串末尾加上'#', 相当于结束符号, 避免特判

    long long a = 0, b = 0;  //a: 未知数前的系数, b: 常数项
    char x;
    long long num = 0, flag = 0, pos = 1;  //flag: 当前数字项是否是负数, pos: 1表示在等号左边,-1表示在等号右边,
                                           //这里相当于将未知数的系数全部移项至等号左边,常数项全部移项至等号右边
    for (int i = 0; i < s.size(); ++i) {
        if (!isdigit(s[i])) {
            if (flag) num *= -1;

            if (isalpha(s[i])) {
                x = s[i];
                a += pos * num;
            }
            else b -= pos * num;

            num = flag = 0;
            if (s[i] == '-') flag = 1;
            if (s[i] == '=') pos = -1;
        }
        else num = num * 10 + s[i] - '0';
    }
    if (!b) printf("%c=0.000\n", x);    //特判
    else printf("%c=%.3f\n", x, 1.0 * b / a);

    return 0;
}

AC提交记录

(https://www.luogu.com.cn/record/176544896)
image

平均 \(3\) ~ \(4ms\),没什么问题

posted @   medicos  阅读(60)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示