首页 > 其他分享 >[NOIP2000 普及组] 计算器的改良

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

时间:2022-09-21 19:00:39浏览次数:80  
标签:NOIP2000 改良 equation 计算器 back substr num ans include

[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;
}

标签:NOIP2000,改良,equation,计算器,back,substr,num,ans,include
From: https://www.cnblogs.com/jyhlearning/p/16716634.html

相关文章

  • 使用 JavaScript 的 Glassmorphic 计算器
    使用JavaScript的Glassmorphic计算器大家好!欢迎来到编码扭矩.在本博客中,我将向您解释如何使用HTML、CSS和JavaScript制作Glassmorphic计算器。这将是一个分......
  • [NOIP2000 提高组] 单词接龙
    [NOIP2000提高组]单词接龙题目背景注意:本题为上古NOIP原题,不保证存在靠谱的做法能通过该数据范围下的所有数据。题目描述单词接龙是一个与我们经常玩的成语接龙相......
  • 实例-rust-打开计算器
    https://rust.ffactory.org/std/process/struct.Command.html进程生成器,提供对如何生成新进程的细粒度控制。可以使用Command::new(program)生成默认配置,其中program......
  • Js-实现简易加减乘除计算器
                                     今日小案例,用Js实现一个小小的计算器 <!DOCTYPEhtml><html......
  • 力扣227(java)-基本计算器Ⅱ(中等)
    题目:给你一个字符串表达式s,请你实现一个基本计算器来计算并返回它的值。整数除法仅保留整数部分。你可以假设给定的表达式总是有效的。所有中间结果将在 [-231,231......
  • 范例:存款复利计算器
    #include<iostream>usingnamespacestd;intmain(){doubler,m,y;cout<<"*****复利计算器****"<<endl;cout<<"银行年利率:(%)";cin>>r;cout<<"\r......
  • P1004 [NOIP2000 提高组] 方格取数 题解
    [NOIP2000提高组]方格取数题目描述设有\(N\timesN\)的方格图\((N\le9)\),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字\(0\)。如下图所示(见样例):......
  • MFC表达式计算器
    MFC表达式计算器《mfc表达式计算器》该程序应该是一个mfc窗口程序,应该基于对话框。1、支持基本运算符:括号()、+,-,*,/。2、支持复杂运算符:三角函数-sin(x)/cos(x)/tan(x)/......
  • leetcode 227. Basic Calculator II 基本计算器 II(中等)
    一、题目大意给你一个字符串表达式s,请你实现一个基本计算器来计算并返回它的值。整数除法仅保留整数部分。你可以假设给定的表达式总是有效的。所有中间结果将在[-23......
  • 使用程序员计算器计算内存地址以及查找崩溃代码的内存位置找到对应代码
    程序员计算器说明这个咋算呢,就直接打这个内存地址在算的时候0是不看的,DEC是十进制,HEX/H是16进制......