CSP历年复赛题-P1022 [NOIP2000 普及组] 计算器的改良

原题链接:https://www.luogu.com.cn/problem/P1022

题意解读:求解一元一次方程。

解题思路:

直接采用模拟法,对字符串进行解析

设x保存未知数字母

设lx保存"="左边的未知数系数,多个系数要累加

设l保存"="左边的整数,多个整数要累加

设rx保存"="右边的未知数系数,多个系数要累加

设r保存"="右边的整数,多个整数要累加

则一元二次方程表示为:lx * x + l = rx * x + r,移项可得x=(r - l) / (lx - rx)

剩下要解决的就是字符串的处理问题

从字符串提取整数,可以采用num = num * 10 + c - '0'的方法

用1或-1来表示符号正、负

注意:当r - l == 0时,结果为0.000,需要特殊处理,否则可能出现-0.000的情况。

具体逻辑参考代码。

100分代码:

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

int main()
{
    char c, x; //c:输入  x:未知数
    int sign = 1; //符号
    int num = 0; //数字

    //lx:左边的未知数系数,l:左边的整数,rx:右边的未知数系数,r:右边的整数
    int lx = 0, l = 0, rx = 0, r = 0; 
    while(cin >> c)
    {
        if(c >= '0' && c <= '9') num = 10 * num + c - '0';
        if(c >= 'a' && c <= 'z')
        {
            x = c; //保存未知数字母
            if(num == 0) num = 1; //未知数系数如果没有,则默认为1
            lx += sign * num; //未知数系统累加
            num = 0; //清0
        }
        if(c == '+' || c == '-')
        {
            l += sign * num; //先累加前面的整数
            sign = (c == '+') ? 1 : -1; //再更新符号
            num = 0; //清0
        }
        if(c == '=')
        {
             l += sign * num; //先累加前面的整数
             sign = 1;
             num = 0;
             break;
        }
    }
    while(cin >> c)
    {
        if(c >= '0' && c <= '9') num = 10 * num + c - '0';
        if(c >= 'a' && c <= 'z')
        {
            x = c; //保存未知数字母
            if(num == 0) num = 1; //未知数系数如果没有,则默认为1
            rx += sign * num; //未知数系统累加
            num = 0; //清0
        }
        if(c == '+' || c == '-')
        {
            r += sign * num; //先累加前面的整数
            sign = (c == '+') ? 1 : -1; //再更新符号
            num = 0; //清0
        }
    }
    r += sign * num; //累加最后的整数

    if(r - l == 0) printf("%c=0.000", x);
    else printf("%c=%.3lf", x, 1.0 * (r - l) / (lx - rx));

    return 0;
}

 

posted @ 2024-05-21 14:51  五月江城  阅读(106)  评论(0编辑  收藏  举报