【NOIP2000】计算器的改良
【题目描述】
NCL 是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能。实验室将这个任务交给了一个刚进入的新手 ZL 先生。
为了很好的完成这个任务,ZL 先生首先研究了一些一元一次方程的实例:
4+3x=8 6a-5+1=2-2a -5+12y=0
ZL先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母及+、-、=这三个数字符号(当然,符号“-”既可以作减号,也可以做负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。
你可假设对键入的方程的正确性的判断是由另一个程序员在做,或者说可认为键入的一元一次方程均为合法的,且有唯一实数解。
【输入描述】
一个一元一次方程。
【输出描述】
解方程的结果(精确到小数点后三位)。
【样例输入】
6a-5+1=2-2a
【样例输出】
a=0.750
【题目分析】
0.明白一件事,未知数=常数和 / 系数和
比如样例中的 6a-5+1=2-2a,化简一下就是 8a=6或者6=8a 另外注意一些特殊情况,比如分母不能为0
1.题目要求解一元一次方程,难点在于负号和等号的处理(负号乘-1就行)
2.题目输入的字符,需要把数字字符(0~9)转换成数字进行计算
3.未知数不确定是哪个字母,其实无所谓,只要是在(a~z之间就行)
4.如果遇到等号,做相反操作
5.注意数据不一定是个位数,比如25a+12=10a这种情况。注意计算出合适的数据
6.注意一些特判情况,比如未知数系数是1的情况
【参考答案】
/** NOIP 2000 计算器的改良 **/ #include<bits/stdc++.h> using namespace std; int suma=0,sumb=0; //分别表示系数和、常数和 char c; //用来存储未知数字符 int flag=0; //有没有遇到等号,遇到前后做相反操作。 int sym=1; //1表示正,0表示负 string s; //待输入字符串 int temp=0; //临时变量,用来存储过程数据, int main(){ cin>>s; for(int i=0;i<s.size();){ // cout<<"si= "<<s[i]<<" "; //如果遇到数字 while(s[i]>='0' && s[i]<='9'){ temp=temp*10 + s[i]-'0'; //遇到数字进行转换 i++; //下一个 } // cout<<"temp1="<<temp<<",suma="<<suma<<",sumb="<<sumb<<endl; //如果遇到字母 if(s[i]>='a' && s[i]<='z'){ c=s[i]; //保留下未知数 if(i==0){ temp=1; //注意特判,比如 a+2a=3这种类型,首个字母的系数应该是1 } temp =temp*sym; //乘一次符号 if(flag==0){ suma+=temp; //系数部分,在等号左边是加法, }else{ suma-=temp; //否则是减法 } // cout<<"temp2="<<temp<<",suma="<<suma<<",sumb="<<sumb<<endl; }else{ //不是字母,就是符号 if(temp!=0){ temp =temp*sym; //乘一次符号 if(flag==0){ sumb-=temp; //常数部分 }else{ sumb+=temp; } } // cout<<"temp3="<<temp<<",suma="<<suma<<",sumb="<<sumb<<endl; if(s[i]=='+'){ sym=1; }else if(s[i]=='-'){ sym=-1; }else{ flag=1; //等于号情况 sym=1; } } temp=0; //临时变量归0 i++; //下一个字符,这么写的原因是防止遇到结尾是数字的情况无法进入判断 } // cout<<sumb<<endl<<suma; printf("%c=%.3lf\n",c,sumb*1.0/suma); return 0; }
扫描二维码推送至手机访问。
版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。