题解 P1689 【方程求解】

· · 题解

首先,先看一下这道题可能需要什么算法

咦?这怎么和猪国*一样啊

哈哈哈哈哈

好了不闹了

这道题需要进行字符串模拟,但是这道题的表达式里会有空格和回车,就像x +y = z这样,这就需要过滤空格了。不过scanf("%c",&ch)是可以读入空格和回车的

所以我们在读入是可以使用

while(scanf("%c",&s[i++])!=EOF);
len=i-1;

进行读入。

下面就开始模拟了(敲黑板)

因为在读入时没有过滤空格(scanf都读进去了),所以模拟时需要过滤空格。显然需要判断如果是空格就continue。

而题目中表达式的表示方法是x+(或者-)y=z,所以在整个表达式中出现非数字字符只能是+(-)和=,空格已经被过滤。所以这把整个表达式分成了三部分,每个部分都是一个整数,我们可以用x,y,z来表示。

模拟过程我们需要两个状态变量,一个是3个状态,表示当前在表达式的哪个部分,另一个有两个状态,表示表达式是加法还是减法。所以模拟时需要分类讨论符号,具体的模拟过程在代码中解释

#include<bits/stdc++.h>
using namespace std;
const int INF=2147483647;//这里可以看出哪个数是未给出的数
char s[100];
int main()
{
    int len,i=1,x=0,y=0,z=0,op=0;
    bool op_add=true;
    //这里op表示当前处于表达式的哪个部分,op_add表示当前表达式是加法还是减法,x,y,z都要给初值,否则后面会出错
    while(scanf("%c",&s[i++])!=EOF);//读入,暂时不忽略空格
    len=i-1;//长度,在读入时多了一个,需要-1
    for(i=1;i<=len;i++)
    {
        if(s[i]==' ') continue;//这里过滤空格
        else if(s[i]>='0' && s[i]<='9')//处理数字
        {
            if(op==0) x=x*10+(s[i]-'0');//看这是在哪个部分
            else if(op==1) y=y*10+(s[i]-'0');//不同的部分表示不同的数
            else if(op==2) z=z*10+(s[i]-'0');//如果这里没给初值的话,那这就是乱码,会WA
        }
        else if(s[i]=='+') op=1;//如果遇到'+',说明已经到了第二部分(+或-和=号之间)
        else if(s[i]=='-') op=1,op_add=false;//如果是-,那就把op_add=false,后面需要判断
        else if(s[i]=='=') op=2;//到=了,说明到第三部分了
        else if(s[i]=='?')//遇到了未知数
        {
            if(op==0) x=INF;//记录下来
            else if(op==1) y=INF;//INF相当于标记
            else if(op==2) z=INF;
        }
    }
    if(op_add)//处理完毕,如果表达式是加法
    {
        if(x==INF) printf("%d",z-y);//加数=和-另一个加数
        else if(y==INF) printf("%d",z-x);
        else if(z==INF) printf("%d",x+y);//和=...
    }
    else//如果是减法
    {
        if(x==INF) printf("%d",z+y);//同理了呗~~
        else if(y==INF) printf("%d",x-z);
        else if(z==INF) printf("%d",x-y);
    }
//  printf("\n%d %d %d",x,y,z);//这是调试的语句
    return 0;//结束
}

最后求管理大大过QAQ