洛谷P1022计算器的改良(模拟)

题目背景

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;
}

写的太丑了吧

发布了30 篇原创文章 · 获赞 9 · 访问量 1313

猜你喜欢

转载自blog.csdn.net/Zhang_sir00/article/details/100165732