jyhlearning

导航

[NOIP2000 普及组] 计算器的改良

[NOIP2000 普及组] 计算器的改良

题目背景

NCL 是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能。实验室将这个任务交给了一个刚进入的新手 ZL 先生。

题目描述

为了很好的完成这个任务,ZL 先生首先研究了一些一元一次方程的实例:

  • \(4+3x=8\)
  • \(6a-5+1=2-2a\)
  • \(-5+12y=0\)

ZL 先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母及 +-= 这三个数学符号(当然,符号“-”既可作减号,也可作负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。

你可假设对键入的方程的正确性的判断是由另一个程序员在做,或者说可认为键入的一元一次方程均为合法的,且有唯一实数解。

输入格式

一个一元一次方程。

输出格式

解方程的结果(精确至小数点后三位)。

样例 #1

样例输入 #1

6a-5+1=2-2a

样例输出 #1

a=0.750

我的解答

我是很纯粹的模拟,感觉麻烦死了,看了大佬的做法感觉自愧不如,还有很多东西要学习。另外在这题中需要注意在浮点数中是有-0.0的,因此要注意将-0以0的形式输出

#include <iostream>
#include <string>
#include <vector>
#include <regex>
using namespace std;
vector<string> left_num,right_num;
string equation;
regex r("-?([0-9]+)"),r1("-?([a-z])");
char a;
const float eps=0.0000001;
void get_half_equation(string str, vector<string>& v)
{
    int i=0;
    while(i<str.size())
    {
        if(str[i]=='+')i++;
        else
        {
            for(int j=1;j<=str.size()-i;j++)
            {
                if(str[i+j]=='+'||str[i+j]=='-'||i+j==str.size())
                {
                    string temp = str.substr(i,j);
                    if(regex_match(temp,r1))
                        temp.insert(temp.size()-1,"1");
                    v.push_back(temp);
                    i+=j;
                    break;
                }
            }
        }
    }
}
void classify()
{
    vector<string> temp1;
    vector<string> temp2;
    for(string num:left_num)
    {
        if(regex_match(num,r))
        {
            if(num[0]=='-')temp2.push_back(num.substr(1));
            else temp2.push_back("-"+num);
        }
        else
        {
            a=num.back();
            temp1.push_back(num.substr(0,num.size()-1));
        }
    }
    for(string num:right_num)
    {
        if(regex_match(num,r))
            temp2.push_back(num);
        else
        {
            if(num[0]=='-')
                num=num.substr(1);
            else
                num="-"+num;
            a=num.back();
            temp1.push_back(num.substr(0,num.size()-1));
        }
    }
    left_num=temp1;
    right_num=temp2;
}
float add_num(vector<string> nums)
{
    int ans=0;
    bool is_negative=false;
    for(string num:nums)
    {
        if(num[0]=='-')ans+=(-1*stoi(num.substr(1)));
        else ans+=stoi(num);
    }
    return ans;
}
int main()
{
    cin>>equation;
    int x=equation.find('=');
    get_half_equation(equation.substr(0,x),left_num);
    get_half_equation(equation.substr(x+1),right_num);
    classify();
    float ans = add_num(right_num)/add_num(left_num);
    ans=(ans<eps&&ans>-eps)?0.0:ans;
    printf("%c=%.3f",a,ans);
    return 0;
}

第二次优化版本,和上一种做法的本质区别就是直接统计未知数域的值和实数域的值,并以等号为界限,通过乘-1来实现移项操作

#include <iostream>
#include <string>
#include <regex>
using namespace std;
const float eps=0.00001;
regex r("-?([0-9]+)");
string equation;
int main()
{
    cin>>equation;
    int i=0,flag=1,k=0,b=0;
    char x;
    while(i<equation.size())
    {
        if(equation[i]=='+')i++;
        else if(equation[i]=='=')
        {
            i++;
            flag=-1;
        }
        else
        {
            for(int j=1;j+i<=equation.size();j++)
            {
                if(equation[i+j]=='-'||equation[i+j]=='+'||equation[i+j]=='='||i+j==equation.size())
                {
                    int is_negative=1;
                    string temp=equation.substr(i,j);
                    if(temp[0]=='-')
                    {
                        is_negative=-1;
                        temp=temp.substr(1);
                    }
                    if(regex_match(temp,r))
                        k+=stoi(temp)*is_negative*flag;
                    else
                    {
                        x=temp.back();
                        if(temp.size()==1)
                            b+=1*is_negative*flag;
                        else
                            b+=stoi(temp.substr(0,temp.size()-1))*is_negative*flag;
                    }
                    if(i+j==equation.size()-1)i=equation.size();
                    i+=j;
                    break;
                }
            }
        }
    }
    float ans=k/(b*-1.0);
    ans=(ans<eps&&ans>-eps)?0:ans;
    printf("%c=%.3f",x,ans);
    return 0;
}

posted on 2022-09-21 18:55  jyhlearning  阅读(90)  评论(0编辑  收藏  举报