🏆今日学习目标:
🍀学习了解P1022 [NOIP2000 普及组] 计算器的改良
✅创作者:贤鱼
⏰预计时间:15分钟
[NOIP2000 普及组] 计算器的改良
题目背景
NCL 是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能。实验室将这个任务交给了一个刚进入的新手 ZL 先生。
题目描述
为了很好的完成这个任务,ZL 先生首先研究了一些一元一次方程的实例:
- $4+3x=8$。
- $6a-5+1=2-2a$。
- $-5+12y=0$。
ZL 先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母及 +
、-
、=
这三个数学符号(当然,符号“-
”既可作减号,也可作负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。
你可假设对键入的方程的正确性的判断是由另一个程序员在做,或者说可认为键入的一元一次方程均为合法的,且有唯一实数解。
输入格式
一个一元一次方程。
输出格式
解方程的结果(精确至小数点后三位)。
样例 #1
样例输入 #1
6a-5+1=2-2a
样例输出 #1
a=0.750
思路
一元一次方程,不需要配方啥的乱七八糟,所以我们直接存下x的系数和常数就可以
我们默认将所有的常数移到右边
这里我们要分开处理
1等号两边
如果在等号左边,有未知数的一项直接按照加减处理就可以,如果在另一边,转换的时候需要变号
常数项与其相反,在等号左边的话需要变号,右边则不需要
==等号处理完了,需要处理一下括号了==
处理括号
在上面的基础上,括号里变一下号就好了
==答案记得开double==
AC代码
#include<cmath>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char a[10006];
int main(){
cin>>a;
int c=strlen(a);
int wc=0;
char sss;//sss储存一下未知数,这个题不一定全是xy之类的
for(int i=0;i<=c;i++){//下面全是按照题目要求处理就可以了
if(a[i]=='('){
wc=1;
c-=1;
for(int j=i;j<=c;j++){
a[j]=a[j+1];
}
}
if(a[i]==')'){
wc=0;
c-=1;
for(int j=i;j<=c;j++){
a[j]=a[j+1];
}
}
if(wc){
if(a[i]=='+'){
a[i]='-';
}else if(a[i]=='-'){
a[i]='+';
}
}
}
a[c]='-';
for(int i=0;i<=c;i++){
if(a[i]!='='&&a[i]!='-'&&a[i]!='+'&&!isdigit(a[i])){
sss=a[i];
a[i]='x';
}
}
int fg=0;
double wcc=0;
double x=0,y=0;
int p=1;
for(int i=0;i<=c;i++){
if(a[i]=='x'&&(!isdigit(a[i-1])))
{
wcc=1;
}
if (isdigit(a[i]))
wcc=wcc*10+(a[i]-'0');
if((a[i-1]<='9'&&a[i-1]>='0')&&(a[i]=='-'||a[i]=='+'||a[i]=='=')){
wcc=wcc*p;
if(!fg){
y=y-wcc;
}else{
y=y+wcc;
}
wcc=0;
}else if(a[i]=='x'){
wcc=wcc*p;
if(!fg){
x+=wcc;
}else{
x-=wcc;
}
wcc=0;
}
if(a[i]=='+'||a[i]=='='||a[i]=='-'){
if(a[i]=='-'){
p=-1;
}else {
p=1;
}}
if(a[i]=='='){
fg=1;
}
}
double ww;
ww=y/x;
if(ww==0) ww=0;
cout<<sss<<"=";
printf("%.3lf\n",ww);
}