题目链接
题目描述
NCL是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能。实验室将这个任务交给了一个刚进入的新手ZL先生。为了很好的完成这个任务,ZL先生首先研究了一些一元一次方程的实例:
4+3x=8
6a-5+1=2-2a
-5+12y=0
ZL先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母及+、-、=这三个数学符号(当然,符号"─"既可作减号,也可作负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。
编写程序,解输入的一元一次方程,将解方程的结果(精确至小数点后三位)输出至屏幕。
你可假设对键入的方程的正确性的判断是由另一个程序员在做,或者说可认为键入的一元一次方程均为合法的,且有唯一实数解。
输入
每个测试文件只包含一组测试数据,每组输入一个字符串,表示一个一元一次方程。
输出
对于每组输入数据,解方程的结果(精确至小数点后三位)输出至屏幕。
样例输入
6a-5+1=2-2a
样例输出
a=0.750
题意;数学计算一元一次方程;
解题思路:模拟即可:
当时比赛时,模拟思路是,之间模拟等号左边 ,等号右边找出a的系数,常数,模拟运算;比完赛觉得这样模拟是比较麻烦的,代码和比较长,很耗时间;
所以,我们也可以之间从左到右模拟,标记一下是左边,还是右边即可;
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include<queue>
#include<stack>
#include <math.h>
#include <string.h>
#define ll long long
#define inf 0x3f3f3f3f3f
#define N 1000005
char a[N];
int a1[N],b1[N];
int a2[N],b2[N];
ll cut;
using namespace std;
int main()
{
scanf("%s",a);
int len=strlen(a);
a[len]='*';//这个初始它为一个符号,好让之后,从右到左找两两符号之间的常数;
len++;//这时多一 因为变成了len 个
int k;
char ch;
for(int i=0;i<len;i++)//找未知数字母
{
if(a[i]=='=')
{
k=i;
}
if(a[i]>='a'&&a[i]<='z')
{
ch=a[i];
}
}
int sum;
int op=1;
int pp=1;
for(int i=0;i<=k;i++)//判断出ch这个未知数的系数
{
if(a[i]==ch)//
{
int hh=0;
int jj=1;
sum=0;
for(int j=i-1;j>=0;j--)
{
if(a[j]>='0'&&a[j]<='9')
{
sum+=(a[j]-'0')*jj;//位数 总值
jj*=10;
}
if(a[j]=='-'||a[j]=='+')
{
if(a[j]=='-')//为负标记
{
hh=1;
}
break;
}
}
if(hh==1)//符合-则加-
a1[op++]=(-sum);
else//否则为正
a1[op++]=sum;
}
if(a[i]=='-'||a[i]=='+'||a[i]=='=')//两两符号之间找常数
{
int hh=0;
int jj=1;
sum=0;
for(int j=i-1;j>=0;j--)//注意我是从等号倒回来找的,这样好算数
{
if(a[j]>='0'&&a[j]<='9')
{
sum+=jj*(a[j]-'0');
jj*=10;
}
if(a[j]=='-'||a[j]=='+'||a[j]==ch)//和上面的一样
{
if(a[j]=='-')
{
hh=1;
}
break;
}
}
if(hh==1)
{
b1[pp++]=(-sum);
}
else
b1[pp++]=sum;
}
}
int yy=1;
int oy=1;
//printf("%c\n",a[k+1]);
for(int i=k+1;i<len;i++)//等号右边
{
if(a[i]==ch)
{
int hh=0;
int jj=1;
sum=0;
for(int j=i-1;j>=k+1;j--)
{
if(a[j]>='0'&&a[j]<='9')
{
sum+=(a[j]-'0')*jj;
jj*=10;
}
if(a[j]=='-'||a[j]=='+'||a[j]=='=')
{
if(a[j]=='-')
{
hh=1;
}
break;
}
}
if(hh==1)
a2[oy++]=(-sum);
else
a2[oy++]=sum;
}
if(a[i]=='-'||a[i]=='+'||a[i]=='*')
{
int hh=0;
int jj=1;
sum=0;
for(int j=i-1;j>=k+1;j--)
{
if(a[j]>='0'&&a[j]<='9')
{
sum+=jj*(a[j]-'0');
jj*=10;
}
if(a[j]=='-'||a[j]=='+'||a[j]==ch||a[j]=='=')
{
if(a[j]=='-')
{
hh=1;
}
break;
}
}
if(hh==1)
{
b2[yy++]=(-sum);
}
else
b2[yy++]=sum;
}
}
int aa1=0,bb1=0,aa2=0,bb2=0;
for(int i=0;i<op;i++)//最后模拟算数,将等号左边的常数求和,与未知数的系数求和,右边也同理求
{
aa1+=a1[i];
}
for(int i=0;i<pp;i++)
{
bb1+=b1[i];
}
for(int i=0;i<oy;i++)
{
aa2+=a2[i];
}
for(int i=0;i<yy;i++)
{
bb2+=b2[i];
}
int da=aa1-aa2;
int db=bb2-bb1;
//printf("%d %d %d %d\n",aa1,bb1,aa2,bb2);
printf("%c=%.3lf\n",ch,(db*1.000)/(da*1.000));//保留三位有效数字
return 0;
}