一道非常奇妙的题目。

对于算术表达式一类的问题,能够採用编译原理里的后缀表达式的方式来做。详细做法是分别维护两个栈,一个栈里保存表达式里的数字,还有一个栈里保存表达式里的运算符,给每种运算符一个优先级,我们要维护这个栈的单调性,每次读入运算符中的数字或运算符,读入的是运算符时,若这个运算符比栈顶的运算符优先级低,就弹出栈顶元素。把栈顶的运算符和数字栈里栈顶的两个数字拿出来做一次运算,运算结果再入数字栈。直到运算符栈的栈顶元素优先级比这个运算符低为止。

然后题目有坑点,一是读入的表达式字符串可能有空格,所以不能直接scanf一次搞定读入数据操作。二是推断表达式是否等价时,带入的值假设不好可能会WA,所以为了避免这样的情况的发生,我们代入的数字应该是个小数,用三态函数推断表达式结果是否相等,多代入几个小数计算。基本上不可能出现意外WA的发生。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <map>
#include <cmath> #define MAXN 1000
#define EPS (1e-5) using namespace std; long long stackOfNum[MAXN];
int topNum=0; //保存数字的栈和栈顶下标
char stackOfSign[MAXN];
int topSign=0; //保存运算符号的栈和栈顶下标
bool needPop[50][50]; //needPop[i][j]=true表示当前运算符为i,栈顶运算符为j时须要出栈
bool isTrue[30]; int dcmp(long long a,long long b) //a>b return 1; a=b return 0; a<b return -1
{
if(fabs(a-b)<=EPS)
return 0;
if(a>b)
return 1;
return -1;
} long long cal(long long a,long long b,char cmd)
{
switch(cmd)
{
case '^':
{
long long ans=1;
for(int i=1;i<=(int)b;i++)
ans*=a;
return ans;
}
case '+': return a+b;
case '-': return a-b;
case '*': return a*b;
case '/': return a/b;
}
return 0;
} long long getAns(char s[],int len,long long a) //将表达式的值求出来,len=表达式长度,a=字母a相应的值
{
int p=1; //指针指向当前的表达式下标
topNum=0;
topSign=0;
while(p<=len)
{
while(s[p]==' ') p++;
if(p>len) break;
if(s[p]>='0'&&s[p]<='9') //是数字
{
int nowNum=0;
while(p<=len)
{
if(!(s[p]>='0'&&s[p]<='9')) //如今的s[p]不是数字了
break;
nowNum*=10;
nowNum+=s[p]-'0';
p++;
}
stackOfNum[++topNum]=nowNum; //这个数字进栈
continue;
}
else if(s[p]=='a')
stackOfNum[++topNum]=a; //假设是a,将a相应的数字压入栈
else //s[p]是个运算符,将栈中全部比它优先级
{
while(topSign>0&&topNum>0)
{
if(needPop[s[p]][stackOfSign[topSign]])
{
if(stackOfSign[topSign]=='(') //右括号遇到左括号
{
topSign--;
break;
}
stackOfNum[topNum-1]=cal(stackOfNum[topNum-1],stackOfNum[topNum],stackOfSign[topSign]);
topNum--;
topSign--;
}
else break;
}
if(s[p]!=')') stackOfSign[++topSign]=s[p];
}
p++;
}
while(topSign>0&&topNum>1)
{
stackOfNum[topNum-1]=cal(stackOfNum[topNum-1],stackOfNum[topNum],stackOfSign[topSign]);
topNum--;
topSign--;
}
return stackOfNum[topNum];
} int main()
{
memset(isTrue,true,sizeof(isTrue));
//先打个巨表~!
needPop['^']['^']=true;
needPop['^']['+']=false;
needPop['^']['-']=false;
needPop['^']['*']=false;
needPop['^']['/']=false;
needPop['^']['(']=false;
//----------------------
needPop['+']['^']=true;
needPop['+']['+']=true;
needPop['+']['-']=true;
needPop['+']['*']=true;
needPop['+']['/']=true;
needPop['+']['(']=false;
//----------------------
needPop['-']['^']=true;
needPop['-']['+']=true;
needPop['-']['-']=true;
needPop['-']['*']=true;
needPop['-']['/']=true;
needPop['-']['(']=false;
//----------------------
needPop['*']['^']=true;
needPop['*']['+']=false;
needPop['*']['-']=false;
needPop['*']['*']=true;
needPop['*']['/']=true;
needPop['*']['(']=false;
//----------------------
needPop['/']['^']=true;
needPop['/']['+']=false;
needPop['/']['-']=false;
needPop['/']['*']=true;
needPop['/']['/']=true;
needPop['/']['(']=false;
//----------------------
needPop['(']['^']=false;
needPop['(']['+']=false;
needPop['(']['-']=false;
needPop['(']['*']=false;
needPop['(']['/']=false;
needPop['(']['(']=false;
//----------------------
needPop[')']['^']=true;
needPop[')']['+']=true;
needPop[')']['-']=true;
needPop[')']['*']=true;
needPop[')']['/']=true;
needPop[')']['(']=true;
char s[MAXN];
int n;
long long trueAns1,trueAns2,nowAns1,nowAns2; //trueAns=带入a值后应该得到的答案,nowAns=选择选项中带入a值得到的答案
//scanf("%s",s+1);
gets(s+1);
trueAns1=getAns(s,strlen(s+1),1.4);
trueAns2=getAns(s,strlen(s+1),2.8);
scanf("%d",&n);
gets(s+1);
for(int i=0;i<n;i++)
{
//scanf("%s",s+1);
gets(s+1);
nowAns1=getAns(s,strlen(s+1),1.4);
nowAns2=getAns(s,strlen(s+1),2.8);
if(dcmp(trueAns1,nowAns1)!=0) //trueans==nowans
isTrue[i]=false;
if(dcmp(trueAns2,nowAns2)!=0) //trueans==nowans
isTrue[i]=false;
}
for(int i=0;i<n;i++)
if(isTrue[i])
printf("%c",'A'+i);
printf("\n");
return 0;
}

[Codevs 1107][NOIP 1107]等效表达的更多相关文章

  1. codevs 1018 [noip 2000 提高] 单词接龙

    题目链接:http://codevs.cn/problem/1018/ 题目描述 Description 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母, ...

  2. 使用curl操作openstack swift

    openstack官网有专门的开发者文档介绍如何使用curl操作swift(http://docs.openstack.org/api/openstack-object-storage/1.0/con ...

  3. C语言学习笔记---谭浩强

    前段时间有机会去面试了一次,真是备受“打击”(其实是启发),总的来说就是让我意识到了学习工具和学习技术的区别.所以最近在看一些数据结构和算法,操作系统,python中的并行编程与异步编程等东西.然而数 ...

  4. X-003 FriendlyARM tiny4412 uboot移植之添加相应目录文件

    X-003 FriendlyARM tiny4412 uboot移植之添加相应目录文件 <<<<<<<<<<<<<< ...

  5. [机器学习Lesson 1 Introduction] 机器学习的动机与应用

    1. Machine Learning definition(机器学习定义) Arthur Samuel(1959年)将机器学习非正式定义为:在不直接针对问题进行编程的情况下,赋予计算机学习能力的一个 ...

  6. 由浅入深学习PBR的原理和实现

    目录 一. 前言 1.1 本文动机 1.2 PBR知识体系 1.3 本文内容及特点 二. 初阶:PBR基本认知和应用 2.1 PBR的基本介绍 2.1.1 PBR概念 2.1.2 与物理渲染的差别 2 ...

  7. [深度学习] pytorch学习笔记(2)(梯度、梯度下降、凸函数、鞍点、激活函数、Loss函数、交叉熵、Mnist分类实现、GPU)

    一.梯度 导数是对某个自变量求导,得到一个标量. 偏微分是在多元函数中对某一个自变量求偏导(将其他自变量看成常数). 梯度指对所有自变量分别求偏导,然后组合成一个向量,所以梯度是向量,有方向和大小. ...

  8. Bisecting GlcNAc is a general suppressor of terminal modification of N-glycan (解读人:王茹凯)

    文献名:Bisecting GlcNAc is a general suppressor of terminal modification of N-glycan(平分GlcNAc是N-聚糖末端修饰的 ...

  9. 数据结构--栈 codevs 1107 等价表达式

    codevs 1107 等价表达式 2005年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond     题目描述 Descripti ...

随机推荐

  1. 1.2 Use Cases中 Website Activity Tracking官网剖析(博主推荐)

    不多说,直接上干货! 一切来源于官网 http://kafka.apache.org/documentation/ Website Activity Tracking 网站活动追踪 The origi ...

  2. Spring MVC handler interceptors example--转载

    原文地址:http://www.mkyong.com/spring-mvc/spring-mvc-handler-interceptors-example/ Spring MVC allow you ...

  3. [python]bug和debug

    bug:代码中存在的语法或者逻辑问题 debug:自查和解决代码中的问题 (coding五分钟,debug两小时) 一.出现bug原因的四大类型 1.粗心 1)错误案例 上面这个错误就是因为 if语句 ...

  4. Java基础学习总结(38)——Lombok的使用和原理

    一.项目背景 在写Java程序的时候经常会遇到如下情形:  新建了一个Class类,然后在其中设置了几个字段,最后还需要花费很多时间来建立getter和setter方法  lombok项目的产生就是为 ...

  5. 注意knn与kmeans的区别

    开始的时候,我居然弄混了. knn是分类方法,是通过新加入的节点最接近的N个节点的属性,来判定新的节点. kmeans是聚类方法,是先选择k个点作为k个簇的中点,然后分簇之后重新划定中心点,然后再分簇 ...

  6. TCP超时重传机制

    TCP协议在能够发送数据之前就建立起了"连接".要实现这个连接,启动TCP连接的那一方首先将发送一个SYN数据包.这只是一个不包含数据的数据包, 然后,打开SYN标记.如果另一方同 ...

  7. postman--下载及使用入门

    安装 本文只是基于 Chrome 浏览器的扩展插件来进行的安装,并非单独应用程序. 首先,你要台电脑,其次,安装有 Chrome 浏览器,那你接着往下看吧. 1. 官网安装(别看) 打开官网,http ...

  8. [React Intl] Format a Date Relative to the Current Date Using react-intl FormattedRelative

    Given a date, we’ll use the react-intl FormattedRelative component to render a date in a human reada ...

  9. iOS_04_学习ios开发的准备

    学习ios开发的准备 * 英语水平:看懂26个英文字母. * 计算机专业:不要求计算机专业,但得有脑子. * 学习态度:积极思考.积极动手.能吃苦.有兴趣. * 编程语言:C语言.C++(可选).Ob ...

  10. EL表达式.md

    操作符 描述 . 访问一个Bean属性或者一个映射条目 [] 访问一个数组或者链表的元素 ( ) 组织一个子表达式以改变优先级 + 加 - 减或负 * 乘 / or div 除 % or mod 取模 ...