NOIP 2000 计算器的改良
题目
题目背景
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
ZLZLZL 先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母及+、-、=这三个数学符号(当然,符号“-”既可作减号,也可作负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。
你可假设对键入的方程的正确性的判断是由另一个程序员在做,或者说可认为键入的一元一次方程均为合法的,且有唯一实数解。
输入输出格式
输入格式:一个一元一次方程。
输出格式:解方程的结果(精确至小数点后三位)。
输入输出样例
输入样例#1:
6a-5+1=2-2a
输出样例#1:
a=0.750
分析
不存在的,详见小学五年级课本。
犯的各种阿姆斯特朗回旋乱七八糟的错误
请见程序。
程序
1 #include <bits/stdc++.h> 2 using namespace std; 3 char c, p; 4 double num = 0, x = 0; 5 int a[100], l = 1, mid, flag = 1; 6 int main() 7 { 8 // 从等号分开,前后分两个while来做,要方便一些,省去了很多判断,程序更容易写 9 // 可以先不急着把数字累加起来,否则平添了许多麻烦 10 while (c != '=') 11 { 12 c = getchar(); 13 if (c == '-') 14 ++l, flag = -1; 15 if (c == '+') 16 ++l, flag = 1; 17 if (c >= '0' && c <= '9') 18 if (!a[l]) 19 a[l] = (c-'0')*flag; 20 else 21 a[l] = a[l]*10 + (c-'0')*flag; 22 if (c >= 'a' && c <= 'z') 23 { 24 p = c; 25 if (a[l] != 0) 26 x += a[l], a[l] = 0; 27 else 28 x += flag; // 这里的特殊情况:当出现 +x 或者 -x 的情况时,省略了系数,还要补上flag! 29 --l; 30 } 31 } 32 mid = l, ++l, flag = 1; 33 while (c != '\n') 34 { 35 c = getchar(); 36 if (c == '-') 37 ++l, flag = -1; 38 if (c == '+') 39 ++l, flag = 1; 40 if (c >= '0' && c <= '9') 41 if (!a[l]) 42 a[l] = (c-'0')*flag; 43 else 44 a[l] = a[l]*10 + (c-'0')*flag; 45 if (c >= 'a' && c <= 'z') 46 { 47 p = c; 48 if (a[l] != 0) 49 x -= a[l], a[l] = 0; 50 else 51 x -= flag; // !!!!!!!!!!!!!! 52 --l; 53 } 54 } 55 for (int i = 1; i <= l; i++) 56 if (i <= mid) 57 num -= a[i]; 58 else 59 num += a[i]; 60 // 会有出 -0 的情况?涨姿势。判断一下。 61 if (!(num/x)) 62 cout << p << "=0.000" << endl; 63 else 64 printf("%c=%.3lf\n",p,num/x); 65 return 0; 66 }