洛谷 P1022 计算器的改良

题外话

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

正文

题面

解一元一次方程。(逃

思路

想想七上学的那些方法!

  1. 去分母(这个不用)
  2. 去括号(这个不用)
  3. 移项,合并同类项
  4. 系数化为 1

模拟呗!
首先,怎么存呢?
开一个叫做 Term 的结构体,有两个参数 BaseExpBase 为系数,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 @   A-Problem-Solver  阅读(73)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示