洛谷 P1022 计算器的改良
题外话
听说小伙伴们有人作弊?!!
正文
题面
解一元一次方程。(逃
思路
想想七上学的那些方法!
- 去分母(这个不用)
- 去括号(这个不用)
- 移项,合并同类项
- 系数化为 $ 1 $ 。
模拟呗!
首先,怎么存呢?
开一个叫做 $ Term $ 的结构体,有两个参数 $ Base $ 和 $ Exp $$,$$ Base $ 为系数,$ Exp $ 为次数。
最终结果要两个 $ Term $,一个常数的,一个未知数的。
遍历整个字符串:
- 遇到
+或-,把原先的东西更新到对应的地方(初始是 $ left $,后面变成 $ right $),负数处理一下! - 遇到数字,处理这整个数字。
- 遇到字母,把未知数的
flag标记一下。 - 遇到等号,前面对应的地方肯定是 $ left $,现在变 $ right $。注意要把原先的东西更新一遍。
- 接下来大概就没情况了。
注意! 开始时是未知数的话,数字没有更新,得先置 $ 1 $ 才行!
处理完输入之后:
遍历等号左边的 $ Term $:
如果是常数($ Exp = 0 $),则常数项的减去它。
如果是未知数($ Exp = 1 $),则未知数项的加上它。
右边类似,但是是反过来的,常数项加,未知数减。
最后常数项除以未知数项即可。
要格外注意 $ -0.000 $。(可以用sprintf弄到char数组里,再跟 $ -0.000 $ 比对)
我的独家 Debug 方法
其实讲了思路就有 90 % 的问题能解决了,
所以:
- 考场上没人让你讲对吧?那自己给自己讲一遍!
- 怕讲了被判作弊?在代码里加注释总不会被抓吧!
代码
#include <bits/stdc++.h>
using namespace std;
struct term {
int base;
bool exp;
term(int b = 0, int e = 0) : base(b), exp(e) {}
};
vector<term> l;
vector<term> r;
int main() {
string s;
cin >> s;
int num = (s[0] != '+' && s[0] != '-');
bool lr = false;
bool neg = false;
bool ukn = false;
char ukn_ltr;
s.push_back('+');
for (int i = 0; i < s.size(); i++) {
if (s[i] == '+' || s[i] == '-' || s[i] == '=') {
if (neg) {
if (!lr) {
l.push_back(term(-num, ukn));
} else {
r.push_back(term(-num, ukn));
}
} else {
if (!lr) {
l.push_back(term(num, ukn));
} else {
r.push_back(term(num, ukn));
}
}
num = 0;
lr |= (s[i] == '=');
neg = (s[i] == '-');
ukn = false;
} else if ('a' <= s[i] && s[i] <= 'z') {
ukn = true;
ukn_ltr = s[i];
} else if ('0' <= s[i] && s[i] <= '9') {
num = 0;
while ('0' <= s[i] && s[i] <= '9') {
num = num * 10 + (s[i] - '0');
i++;
}
i--;
}
}
term constants = term(0, 0);
term unknowns = term(0, 1);
for (int i = 0; i < l.size(); i++) {
if (l[i].exp) {
unknowns.base += l[i].base;
} else {
constants.base -= l[i].base;
}
}
for (int i = 0; i < r.size(); i++) {
if (r[i].exp) {
unknowns.base -= r[i].base;
} else {
constants.base += r[i].base;
}
}
double ans = (double)(constants.base) / (double)(unknowns.base);
char tmp[105];
sprintf(tmp, "%.3lf", ans);
if (strcmp(tmp, "-0.000")) {
printf("%c=%.3lf", ukn_ltr, ans);
} else {
printf("%c=0.000", ukn_ltr);
}
return 0;
}

浙公网安备 33010602011771号