解方程(洛谷P1022)

解方程(洛谷P1022\mathcal{解方程(洛谷P1022)}

题目大意

对于一个一元一次方程,其中:

  • 包含整数、小写字母及 +=+、-、= 这三个数学符号(当然,符号 - 既可作减号,也可作负号)。
  • 方程中并没有括号
  • 方程中的字母表示未知数
  • 有唯一实数解。(精确至小数点后三位)

解题思路

这道题思维难度和代码难度都不大,就是细节处理有点麻烦,需要判断一些特殊 情况(比如 0.0{\color{RED}-0.0} 什么的)。那我就直接上代码思路了。


因为是一元一次方程,所以最终一定可以化成 kx+b=0kx+b=0 的形式,整理可得 x=bkx=-\frac{b}{k} ,为了减少变量数 方便,将等号右边的多项式直接移到等式左边,即系数均乘 -1,可以用一个变量 nownow 标记一下。


首先大致考虑一下思考的方向,一元一次方程的所有类型:

  • 毒瘤1\color{RED}毒瘤1 +x,−x,例如:
    • 4+x=84+x=8
    • 5y=0−5−y=0
    • a=a/a=a-a=a/a=-a
  • 毒瘤2\color{RED}毒瘤2 未知数前带有一个数,+3x,-3x,+0x,-0x,例如:
    • 4+3x=84+3x=8
    • 43z=84−3z=8
    • 4+0x=44+0x=46a5+1=22a6a−5+1=2−2a
  • 毒瘤3\color{RED}毒瘤3 x=0−x=0,由之前的做法解得 x=0.000x=-0.000,正确解是 x=0.000x=0.000,原因是 00 除以负数会被计算成 0.0-0.0,所以需要特判一下。

学废了吗


接下来就很简单了

做法:

  1. 关于数字的读入

    if (c >= '0' && c <= '9')
    {
        x = x * 10 + c - '0';
    }

    若判定为数字则叠加当前项系数。

  2. 对于符号 ‘+’,‘-’,‘=’ 的处理

    if (c == '+')
    {
        b += now * op * x;
    	x = 0;
    	op = 1;
    }
    if (c == '-')
    {
    	b += now * op * x;
    	x = 0;
    	op = -1;
    }
    if (c == '=')
    {
        b += now * op * x;
        x = 0;
        op = 1;
        now = -1;
    }

    这里 bb 为常数部分的值;nownow 表示相对等号的位置,左边为 11 ,右边为 1-1opop 表示项的系数的正负性,xx 则是项的系数。

    读到加号,常数累加,系数清零,符号标记为正,减号同理。读到等号则需额外将 nownow 改为 1-1

  3. 关于未知数的处理

    if (c >= 'a' && c <= 'z')
    {
        k += now * op * x;
        x = 0;
        a = c;
        res = 0;
    }

    若判定为小写字母,则将未知数的系数累加,项系数清零,并标记未知数名 aa

  4. 解决毒瘤1\color{RED}毒瘤1

    那还不简单,没有读进数就默认乘 1 就好了嘛

    if (c >= 'a' && c <= 'z')
    {
    	x ? k += now *f *x : k += now * f * 1;
    	x = 0;
    	a = c;
    }
  5. 解决毒瘤2\color{RED}毒瘤2

    这就需要引入一个新的变量 resres 来标记是否有系数的读入。至于 resres 的处理,只需要在读到数字时将 resres 置为 11 ,读到其它字符都将 resres 置为 00 就行了。

    if (c >= 'a' && c <= 'z')
    {
        if (res)
        {
            k += now * op * x;
            x = 0;
        }
        else
            k += now * op;
        a = c;
        res = 0;
    }
    else if (c >= '0' && c <= '9')
    {
        x = x * 10 + c - '0';
        res = 1;
    }
    else if (c == '+')
    {
        b += now * op * x;
        x = 0;
        op = 1;
        res = 0;
    }
    else if (c == '-')
    {
        b += now * op * x;
        x = 0;
        op = -1;
        res = 0;
    }
    else if (c == '=')
    {
        b += now * op * x;
        x = 0;
        op = 1;
        now = -1;
        res = 0;
    }
  6. 解决毒瘤3\color{RED}毒瘤3 那还不简单

    if (ans == -0)
        ans = 0;

AC codeAC \ code

#include <bits/stdc++.h>
using namespace std;
int op = 1, now = 1, k, x, b;
char a, c;
bool res;
double ans;
signed main()
{
    c = getchar();
    while (1)
    {
        if (c >= 'a' && c <= 'z')
        {
            if (res)
            {
                k += now * op * x;
                x = 0;
            }
            else
                k += now * op;
            a = c;
            res = 0;
        }
        else if (c >= '0' && c <= '9')
        {
            x = x * 10 + c - '0';
            res = 1;
        }
        else if (c == '+')
        {
            b += now * op * x;
            x = 0;
            op = 1;
            res = 0;
        }
        else if (c == '-')
        {
            b += now * op * x;
            x = 0;
            op = -1;
            res = 0;
        }

        else if (c == '=')
        {
            b += now * op * x;
            x = 0;
            op = 1;
            now = -1;
            res = 0;
        }
        else
        {
            b += now * op * x;
            break;
        }
        c = getchar();
    }
    ans = (double)-b / k;
    if (ans == -0)
        ans = 0;
    printf("%c=%.3lf", a, ans);
    return 0;
}
posted @ 2021-06-22 21:53  蒟蒻orz  阅读(8)  评论(0编辑  收藏  举报  来源