题目背景
NCL 是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能。实验室将这个任务交给了一个刚进入的新手 ZL 先生。
题目描述
为了很好的完成这个任务,ZL 先生首先研究了一些一元一次方程的实例:
- 4+3x=84+3x=84+3x=8。
- 6a−5+1=2−2a6a-5+1=2-2a6a−5+1=2−2a。
- −5+12y=0-5+12y=0−5+12y=0。
ZL 先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母及 +、-、= 这三个数学符号(当然,符号“-”既可作减号,也可作负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。
你可假设对键入的方程的正确性的判断是由另一个程序员在做,或者说可认为键入的一元一次方程均为合法的,且有唯一实数解。
输入格式
一个一元一次方程。
输出格式
解方程的结果(精确至小数点后三位)。
输入输出样例 #1
输入 #1
6a-5+1=2-2a
输出 #1
a=0.750
【题目解析】
首先我们要想想,如果让我们来接一元一次方程,我们应该如何解。
基本步骤如下:
1.合并同类项
2.将常数项移到等号右边,将未知数项移到等号左边
3.系数化为一
那么我们考虑如何对于上述操作,用代码来实现。
步骤1
对于第二步,我们可以考虑维护等号两边的未知数项系数和常数项(用一个变量)。每次找到一个未知数项系数或常数项都将其累加到这个变量上
这里有一个细节,如果出现了如a或-a这样的未知数项,我们就无法求出它的系数。所以我们可以做一个预处理,即在a或-a的未知数前添加一个1
步骤2
对于第2步,我们应该能想起来一句话“移项要变号”这一句经典的数学老是台词,那么操作 2 就可以看作是用等号左边的未知数项系数减去等号右边的未知数项系数,用等号右边的常数项减去等号左边的常数项。
步骤3
对于第三步,实现是容易的,但是有一个容易被忽略的细节,即 0÷(−1) 的值默认输出是 −0.000(保留三位小数)
步骤4
把代码完完整整地粘贴到提交框,不要少交“}"哦,还有十年OI一场空,不开longlong见祖宗~
【代码展示】
#include<bits/stdc++.h>
#define int long long
using namespace std;
string F;
char x;
int get(int &i)
{
int s=0;
while('0'<=F[i]&&F[i]<='9'&&i<F.size()) s=s*10+F[i++]–'0';
return s;
}
signed main()
{
cin>>F;
F=" "+F;
for(int i=0;i<F.size();i++){
if(isalpha(F[i])) x=F[i];
if(F[i]=='-'||F[i]=='+'||F[i]==' ')
if(isalpha(F[i+1])) F=F.substr(0,i+1)+"1"+F.substr(i+1);
}
int nxt=–1;
int Lc=0,Rc=0,Lx=0,Rx=0;
//处理等号左边
for(int i=0;i<F.size();i++)
if(F[i]=='=') {
nxt=i;
break;
// 找到等号,跳出
}
else if(F[i]=='-'){
i++;
int t=get(i);
if(F[i]==x) Lx-=t,i++;
else Lc-=t;
i—;
}
else if(isdigit(F[i])){
int t=get(i);
if(F[i]==x) Lx+=t,i++;
else Lc+=t;
i—;
}
for(int i=nxt+1;i<F.size();i++)
if(F[i]=='-'){
i++;
int t=get(i);
if(F[i]==x) Rx-=t,i++;
else Rc-=t;
i—;
}
else if(isdigit(F[i])){
int t=get(i);
if(F[i]==x) Rx+=t,i++;
else Rc+=t;
i—;
}
int X=0,C=0;
X=Lx–Rx;
C=Rc–Lc;
if(C==0) cout<<x<<"=0.000";
else cout<<x<<"="<<fixed<<setprecision(3)<<(double)C*1.0/X*1.0;
return 0;//完结撒花(*^▽^*)
}






