[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 ...
随机推荐
- Iptables-主机防火墙设置
基于Iptables构建主机防火墙 Iptables优点: 数据包过滤机制,它会对数据包包头数据进行分析. 1.1.1 加载相关薄块到内核 [root@centos7 ~]# lsmod | egre ...
- 2.JPA学习总结
转自:https://shmilyaw-hotmail-com.iteye.com/blog/1969190 前言 最近在做一个项目的时候因为牵涉到要对数据库的操作,在最开始实现的时候采用了直接的JD ...
- 微信支付v2开发(6) 发货通知
本文介绍微信支付中发货通知功能的实现. 一.发货通知 为了更好地跟踪订单的情况,需要第三方在收到最终支付通知之后,调用发货通知API告知微信后台该订单的发货状态. 发货时间限制:虚拟.服务类24小时内 ...
- iOS开发 非常全的三方库、插件、大牛博客等等
UI 下拉刷新 EGOTableViewPullRefresh- 最早的下拉刷新控件. SVPullToRefresh- 下拉刷新控件. MJRefresh- 仅需一行代码就可以为UITableVie ...
- python3 turtle 画围棋棋盘
python3 环境 利用turtle模块画出 围棋棋盘 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan impor ...
- NSDate时间
NSDate 使用 ios时间的秒数 取当前时间的秒数 NSTimeInterval time = [[NSDate date] timeIntervalSince1970]; long long i ...
- Android java.lang.IllegalArgumentException: Object returned from onCreateLoader must not be a non-static inn
AsyncTaskLoader: http://developer.Android.com/intl/zh-CN/reference/android/content/AsyncTaskLoader.h ...
- NIO 入门(转)
NIO 入门 Greg Travis2003 年 11 月 17 日发布 分享此页面 WeiboGoogle+用电子邮件发送本页面 20 在开始之前 关于本教程 新的输入/输出 (NIO) 库是在 J ...
- Windows中DLL文件的意义及其作用
Windows中DLL文件的意义及其作用 DLL是Dynamic Link Library的缩写,意为动态链接库.DLL文件即动态链接库文件,是一种可执行文件,它允许程序共享执行特殊任务所必需的代码和 ...
- ImageView的圆角半径
// 设置imageview的圆角半径 UIImageView *imageView = (UIImageView *)[cell viewWithTag:tag]; imageView.layer. ...