题目背景
NCL是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能。实验室将这个任务交给了一个刚进入的新手ZL先生。
题目描述
为了很好的完成这个任务,ZL先生首先研究了一些一元一次方程的实例:
4+3x=8
6a−5+1=2−2a
−5+12y=0
ZL先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母及+、-、=这三个数学符号(当然,符号“-”既可作减号,也可作负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。
你可假设对键入的方程的正确性的判断是由另一个程序员在做,或者说可认为键入的一元一次方程均为合法的,且有唯一实数解。
输入格式
一个一元一次方程。
输出格式
解方程的结果(精确至小数点后三位)。
输入输出样例
输入1
6a-5+1=2-2a
输出1
a=0.750
让我们回顾一下以前是怎么解方程的…
利用多项式合把问题化简为ax=b的形式,最后b\a就是答案.
然后就是模拟多项式的合并了,等号左边的常数项要变号,等号右边的未知项系数要变号,定义两个flag来模拟这个过程就OK啦.
另外要注意
- 因为精度问题-1/0的值会写成-0.000,需要特判…
- 未知项的系数为1或-1时有可能会写成a或-a.
ACCODE
#include <iostream>
#include <cstdio>
using namespace std;
int flag1=1;
int flag2=-1;
string s;
double getnum(int &i)
{
double ans=0;
for(;i<s.size();i++)
{
if(s[i]>='0'&&s[i]<='9')
{
ans*=10;
ans+=(s[i]-'0');
}
else
break;
}
return ans;
}
char getk()
{
for(int i=0;i<s.size();i++)
{
if(s[i]>='a'&&s[i]<='z')
return s[i];
}
}
int main()
{
getline(cin,s);
s+=' ';
double a=0;
double b=0;
char k=getk();
for(int i=0;i<s.size();i++)
{
if(s[i]=='=')
{
flag1*=-1;
flag2*=-1;
}
else if(s[i]>='0'&&s[i]<'9')
{
double num;
if(i==0||s[i-1]=='+'||s[i-1]=='=')
num=getnum(i);
else
num=-1*getnum(i);
// cout<<num<<endl;
if(i!=s.size()&&s[i]==k)
a+=(flag1*num);
else
{
b+=(flag2*num);
i--;
}
}
else if(s[i]==k)
{
if(i==0||s[i-1]=='+'||s[i-1]=='=')
a+=flag1;
else
a+=(-flag1);
}
}
if(b/a==0)
printf("%c=0.000",k);
else
printf("%c=%.3f",k,b/a);
return 0;
}
写的太丑了吧