洛谷 P1022 计算器的改良

题外话

听说小伙伴们有人作弊?!!

正文

题面

解一元一次方程。(逃

思路

想想七上学的那些方法!

  1. 去分母(这个不用)
  2. 去括号(这个不用)
  3. 移项,合并同类项
  4. 系数化为 $ 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 % 的问题能解决了,
所以:

  1. 考场上没人让你讲对吧?那自己给自己讲一遍!
  2. 怕讲了被判作弊?在代码里加注释总不会被抓吧!

代码

#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;
}
posted @ 2022-08-09 18:36  A-Problem-Solver  阅读(82)  评论(0)    收藏  举报