[Codevs 1107][NOIP 1107]等效表达
一道非常奇妙的题目。
对于算术表达式一类的问题,能够採用编译原理里的后缀表达式的方式来做。详细做法是分别维护两个栈,一个栈里保存表达式里的数字,还有一个栈里保存表达式里的运算符,给每种运算符一个优先级,我们要维护这个栈的单调性,每次读入运算符中的数字或运算符,读入的是运算符时,若这个运算符比栈顶的运算符优先级低,就弹出栈顶元素。把栈顶的运算符和数字栈里栈顶的两个数字拿出来做一次运算,运算结果再入数字栈。直到运算符栈的栈顶元素优先级比这个运算符低为止。
然后题目有坑点,一是读入的表达式字符串可能有空格,所以不能直接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]等效表达的更多相关文章
- codevs 1018 [noip 2000 提高] 单词接龙
题目链接:http://codevs.cn/problem/1018/ 题目描述 Description 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母, ...
- 使用curl操作openstack swift
openstack官网有专门的开发者文档介绍如何使用curl操作swift(http://docs.openstack.org/api/openstack-object-storage/1.0/con ...
- C语言学习笔记---谭浩强
前段时间有机会去面试了一次,真是备受“打击”(其实是启发),总的来说就是让我意识到了学习工具和学习技术的区别.所以最近在看一些数据结构和算法,操作系统,python中的并行编程与异步编程等东西.然而数 ...
- X-003 FriendlyARM tiny4412 uboot移植之添加相应目录文件
X-003 FriendlyARM tiny4412 uboot移植之添加相应目录文件 <<<<<<<<<<<<<< ...
- [机器学习Lesson 1 Introduction] 机器学习的动机与应用
1. Machine Learning definition(机器学习定义) Arthur Samuel(1959年)将机器学习非正式定义为:在不直接针对问题进行编程的情况下,赋予计算机学习能力的一个 ...
- 由浅入深学习PBR的原理和实现
目录 一. 前言 1.1 本文动机 1.2 PBR知识体系 1.3 本文内容及特点 二. 初阶:PBR基本认知和应用 2.1 PBR的基本介绍 2.1.1 PBR概念 2.1.2 与物理渲染的差别 2 ...
- [深度学习] pytorch学习笔记(2)(梯度、梯度下降、凸函数、鞍点、激活函数、Loss函数、交叉熵、Mnist分类实现、GPU)
一.梯度 导数是对某个自变量求导,得到一个标量. 偏微分是在多元函数中对某一个自变量求偏导(将其他自变量看成常数). 梯度指对所有自变量分别求偏导,然后组合成一个向量,所以梯度是向量,有方向和大小. ...
- 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-聚糖末端修饰的 ...
- 数据结构--栈 codevs 1107 等价表达式
codevs 1107 等价表达式 2005年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Descripti ...
随机推荐
- 2. Vue基础语法
模板语法: Mustache语法: {{}} Html赋值: v-html="" 绑定属性: v-bind:id="" 使用表达式: {{ok?'Yes': ...
- GO语言学习(十四)Go 语言数组
Go 语言数组 Go 语言提供了数组类型的数据结构. 数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整形.字符串或者自定义类型. 相对于去声明number0 ...
- Hibernate3.5.4---java application的xml和annotation环境搭建(hibernate.cfg.xml配置文件说明,映射文件Student.hbm.xml说明
http://blog.csdn.net/centre10/article/details/6050466 来自于:http://blog.csdn.net/centre10/article/deta ...
- (转)iptables常用规则:屏蔽IP地址、禁用ping、协议设置、NAT与转发、负载平衡、自定义链
转自:http://lesca.me/archives/iptables-examples.html 本文介绍25个常用的iptables用法.如果你对iptables还不甚了解,可以参考上一篇ipt ...
- BigBoss按键映射
// BigBoss: SBSettings Toggle Spec 按键映射 http://thebigboss.org/guides-iphone-ipod-ipad/sbsettings-tog ...
- Android onLoadFinished与onLoaderReset
onLoadFinished 这个方法是在前面已创建的加载器已经完成其加载过程后被调用,这个方法保证会在应用到加载器上的数据被释放之前被调用.在此方法中,你必须删除所有对旧数据的使用(因为它将很快会被 ...
- C#使用wkhtmltopdf.exe,HTML页面转化为PDF文档
此文用来记录使用wkhtmltopdf.exe在C#代码中将html转换为PDF的过程: 1,在http://wkhtmltopdf.org/downloads.html 下载wkhtmltopdf. ...
- vue中的select框的值动态绑定
<--这两种写法效果一样--> 1: <select v-model="wxStatus"> <option label="已添加" ...
- iOS开发UI篇--一个侧滑菜单SlidingMenu
一.简介 侧滑菜单已经成为app一个极常用的设计,不管是事务类,效率类还是生活类app.侧滑菜单因Path 2.0和Facebook为开发者熟知,国内目前也有很多流行app用到了侧滑菜单,比如QQ.网 ...
- swift项目第十天:网络请求工具类的封装
import UIKit /* 必须先导入头文件:import AFNetworking */ import AFNetworking //MARK:-0:定义枚举:以枚举定义请求网络的get和pos ...