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;
}