一道非常奇妙的题目。

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

然后题目有坑点,一是读入的表达式字符串可能有空格,所以不能直接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. tcl -mode

    -exact     严格匹配(如string equal) -glob 通配符式匹配(string match) -regexp   正则表达式匹配(regexp) array get和array ...

  2. js进阶 14-5 $.getScript()和$.getJSON()方法的作用是什么

    js进阶 14-5 $.getScript()和$.getJSON()方法的作用是什么 一.总结 一句话总结:$.getScript()和$.getJSON()方法专门用来加载JS/JSON文件(远程 ...

  3. js匿名函数(变量加括号就是函数)

    js匿名函数(变量加括号就是函数) 一.总结 变量加括号就是函数,而函数的括号是用来传参的 1.类比:以正常函数去想匿名函数,匿名函数比正常函数只是少了函数名,本质还是一样,该怎么传参还是怎么传参,小 ...

  4. Oracle数据库(三)

    专题一:oracle查询 1.where查询 查询部门编号是1的部门信息 ; 查询姓名是kw的员工,字符串使用‘’,内容大小写敏感 select *from emp where name='kw' 查 ...

  5. UVA 11609 - Teams 组合、快速幂取模

    看题传送门 题目大意: 有n个人,选一个或者多个人参加比赛,其中一名当队长,如果参赛者相同,队长不同,也算一种方案.求一共有多少种方案. 思路: 排列组合问题. 先选队长有C(n , 1)种 然后从n ...

  6. LA 5902 - Movie collection 树状数组(Fenwick树)

    看题传送门 题目大意:XXX喜欢看电影,他有好多好多的影碟,每个影碟都有个独立的编号.开始是从下往上影碟的顺序是n~1,他每次拿出影碟的时候,你需要输出压在该影碟上的有几个.(拿出后其他影碟顺序不变) ...

  7. iOS图片加载-SDWebImage

    一.SDWebImage内部实现过程 1, 入口 setImageWithURL:placeholderImage:options: 会先把 placeholderImage 显示,然后  SDWeb ...

  8. Textillate.js有什么用及使用实例

    Textillate.js有什么用及使用实例 一.总结 一句话总结:Textillate.js – 实现动感的 CSS3 文本动画的简单插件 二.textillate.js 文字动画 textilla ...

  9. 如何使stm32程序更好移植, 结构体相当于define

    原创:转载请标注引用地址 如何定义 led1对应于PA8  呢 :对于我一开始学习的方法:: #include "main.h" #define led1      GPIO_Pi ...

  10. Ubuntu设置IP(VMware9.03)

    说明:在VMware上新安装Ubuntu11.04(64位) vi编辑器特难用,输入老出错,费了老大劲才把IP改好,IP改完之后最好立马重装一个编辑器vim. 设置静态IP: # vi /etc/ne ...