洛谷 P1054 等价表达式 解题报告
P1054 等价表达式
题目描述
明明进了中学之后,学到了代数表达式。有一天,他碰到一个很麻烦的选择题。这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的。
这个题目手算很麻烦,因为明明对计算机编程很感兴趣,所以他想是不是可以用计算机来解决这个问题。假设你是明明,能完成这个任务吗?
这个选择题中的每个表达式都满足下面的性质:
1. 表达式只可能包含一个变量‘a’。 2. 表达式中出现的数都是正整数,而且都小于10000。 3. 表达式中可以包括四种运算‘+’(加),‘-’(减),‘’(乘),‘’(乘幂),以及小括号‘(’,‘)’。小括号的优先级最高,其次是‘’,然后是‘’,最后是‘+’和‘-’。‘+’和‘-’的优先级是相同的。相同优先级的运算从左到右进行。(注意:运算符‘+’,‘-’,‘*’,‘^’以及小括号‘(’,‘)’都是英文字符) 4. 幂指数只可能是1到10之间的正整数(包括1和10)。 5. 表达式内部,头部或者尾部都可能有一些多余的空格。
下面是一些合理的表达式的例子:
((a^1) ^ 2)^3,aa+a-a,((a+a)),9999+(a-a)a,1 + (a -1)3,110^9……
输入输出格式
输入格式:
输入文件的第一行给出的是题干中的表达式。
第二行是一个整数n(2 <= n <= 26),表示选项的个数。后面n行,每行包括一个选项中的表达式。这n个选项的标号分别是A,B,C,D……
输入中的表达式的长度都不超过50个字符,而且保证选项中总有表达式和题干中的表达式是等价的。
输出格式:
输出文件包括一行,这一行包括一系列选项的标号,表示哪些选项是和题干中的表达式等价的。选项的标号按照字母顺序排列,而且之间没有空格。
写完这道题我真想吐血十升。。。
写完这道题我真想吐血十升。。。
写完这道题我真想吐血十升。。。
两个点:
- 完美算法不好写,提供一些质数作为a的值代入计算即可
- 中缀表达式转后(前)缀表达式。
- 中缀表达式转后缀表达式
栈s1存数字或运算符,s2存运算符
从左至右扫描
数字进s1
运算符讨论
若s2栈顶优先级小于进来的,我们认为是合法的(想想为什么等于不行)
否则弹出s2到s1直到合法
括号要多一些判断
非完美算法的细节:
- 为了避免爆ll,要mod一个大质数。
质数不能太大,不然依旧会爆
也不能太小,不然负数模会出问题
(幸运数字1000000007)
不能每一步都膜,会很慢
a的取值要小,否则很可能要出问题
a的数量不能多不能少,否则很可能会出问题
总结:非完美算法要在看脸的基础上,多想想
code:
// luogu-judger-enable-o2
#include <cstdio>
#include <cstring>
#include <stack>
#define ll long long
using namespace std;
int n;
ll last[15],now[15];
int is[260];
ll pre[5]={5,7,11,2,3};
ll mod=1000000007;
char C[60];
void init()
{
for(int i='0';i<='9';i++)
is[i]=1;
is[int('(')]=2;
is[int('+')]=3;
is[int('-')]=3;
is[int('*')]=4;
is[int('^')]=5;
is[int(')')]=6;
is[int('a')]=7;
}
int cnt;
void read()
{
char c=getchar();
while(!is[c]) c=getchar();
cnt=-1;
while(c!='\r')
{
if(is[c])
C[++cnt]=c;
c=getchar();
}
}
struct node
{
int k;//符号1还是数字0
ll c;//数学或者AS码
node(){}
node(int k,ll c)
{
this->k=k;
this->c=c;
}
};
ll get_pow(ll n1,ll n2)
{
ll nn=1;
while(n2)
{
nn=nn*n1;
if(nn>=mod)
nn%=mod;
n2--;
}
return nn;
}
stack <node > s1,s2;
bool get(char *now,int cnt,int flag)
{
while(!s1.empty()) s1.pop();
while(!s2.empty()) s2.pop();
for(int k=0;k<=4;k++)
{
for(int i=0;i<=cnt;i++)
{
ll x=0;
char c=*(now+i);
if(is[c]==1)
{
while(is[c]==1&&i<=cnt) {x=x*10+c-'0';i++;c=*(now+i);}
node tt(0,x);
s1.push(tt);
i--;
}
else if(is[c]==7)
{
node tt(0,pre[k]);
s1.push(tt);
}
else if(is[c]==6)
{
while(!s2.empty())
{
if(s2.top().k&&is[s2.top().c]==2)
break;
s1.push(s2.top());
s2.pop();
}
if(s2.empty())
return false;
else
s2.pop();
}
else
{
node tt(1,c);
while(!s2.empty()&&is[s2.top().c]>=is[c]&&s2.top().c!='('&&c!='(')
{
s1.push(s2.top());
s2.pop();
}
s2.push(tt);
}
}
while(!s2.empty())
{
if(is[s2.top().c]==2)
return false;
s1.push(s2.top());
s2.pop();
}
while(!s1.empty())
{
s2.push(s1.top());
//printf("%d ",s1.top().c);
s1.pop();
}
//printf("\n");
while(!s2.empty())
{
node tt=s2.top();
s2.pop();
if(tt.k)
{
ll t1=s1.top().c;
s1.pop();
ll t2=s1.top().c;
s1.pop();
ll t3;
if(char(tt.c)=='+')
t3=t1+t2;
else if(char(tt.c)=='-')
t3=t2-t1;
else if(is[tt.c]==4)
{
t3=t2*t1;
if(t3>=mod)
t3%=mod;
}
else if(is[tt.c]==5)
t3=get_pow(t2,t1);
tt.c=t3;
tt.k=0;
s1.push(tt);
}
else
s1.push(tt);
}
int ttt=s1.top().c%mod;
if(flag)
last[k]=s1.top().c%mod;
else if(last[k]!=ttt)
return false;
s1.pop();
}
return true;
}
int main()
{
init();
read();
get(C,cnt,1);
char c=getchar();
n=0;
while(!is[c]) c=getchar();
while(c!='\r') {n=n*10+c-'0';c=getchar();}
for(int i=0;i<n;i++)
{
read();
if(get(C,cnt,0))
printf("%c",char(i+'A'));
}
return 0;
}
2018.4.29
洛谷 P1054 等价表达式 解题报告的更多相关文章
- 洛谷 P1054 等价表达式
洛谷 P1054 等价表达式 题目描述 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式, ...
- 洛谷P1054 等价表达式
P1054 等价表达式 题目描述 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的 ...
- [NOIP2005] 提高组 洛谷P1054 等价表达式
题目描述 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数 ...
- 洛谷 P1783 海滩防御 解题报告
P1783 海滩防御 题目描述 WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭 ...
- 洛谷 P4597 序列sequence 解题报告
P4597 序列sequence 题目背景 原题\(\tt{cf13c}\)数据加强版 题目描述 给定一个序列,每次操作可以把某个数\(+1\)或\(-1\).要求把序列变成非降数列.而且要求修改后的 ...
- 洛谷1087 FBI树 解题报告
洛谷1087 FBI树 本题地址:http://www.luogu.org/problem/show?pid=1087 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全 ...
- NOIP2005 等价表达式 解题报告
明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和 ...
- 洛谷 [CQOI2015]选数 解题报告
[CQOI2015]选数 题目描述 我们知道,从区间\([L,H]\)(\(L\)和\(H\)为整数)中选取\(N\)个整数,总共有\((H-L+1)^N\)种方案. 小\(z\)很好奇这样选出的数的 ...
- 洛谷 P2444 [POI2000]病毒 解题报告
P2444 [POI2000]病毒 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已 ...
随机推荐
- ES7 之 Async/await 的使用
在 js 异步请求数据时,通常,我们多采用回调函数的方式解决,但是,如果有多个回调函数嵌套时,代码显得很不优雅,维护成本也相应较高. ES6 提供的 Promise 方法和 ES7 提供的 Async ...
- 聊聊Zookeeper应用场景、架构设计、选主机制
Zookeeper作为一个分布式协调系统提供了一项基本服务:分布式锁服务,分布式锁是分布式协调技术实现的核心内容.像配置管理.任务分发.组服务.分布式消息队列.分布式通知/协调等,这些应用实际上都是基 ...
- Effective C++学习笔记之#define
前言 条款02:尽量以const.enum.inline替换#define:尽可能用编译器代替不必要的预处理器. 内容 一.对于单纯常量 1.const 有两种特殊的const,常量指针和class专 ...
- 10 分钟理解 BFC 原理
一.常见定位方案 在讲 BFC 之前,我们先来了解一下常见的定位方案,定位方案是控制元素的布局,有三种常见方案: 普通流 (normal flow) 在普通流中,元素按照其在 HTML 中的先后位置至 ...
- 关于Runtime error
别人说的,但我感觉是因为你的操作是不符合语言规定的,让编译器无法识别,运行不出
- OneZero第一次随感
>本人基础薄弱,有幸加入这个团队,甚感欣慰.这是本人第一次尝试写博客,说实话,胆怯.因为能力有限,怕技能匮乏,说不好.但是我知道既然加入这个团队,就要为团队负责.万事开头难,过程也挺难(就我个人 ...
- 第七周linux内核分析
可执行程序的装载 作者 黎静+ 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-100002900 ...
- Struts2中的图片验证码
1.Struts中建一个action <action name="Code" class="LoginAction" method="code& ...
- <面向对象程序设计>课程作业一
Github链接 在看完这次的作业要求后我整个人是混乱的,因为作业要求把不同的函数放在一个main函数中:我们之前也是进行了函数分离,但是是放在了不同的文件中.如果要改的话相当于重写(而且这两种形式其 ...
- Beta阶段敏捷冲刺四
一.举行站立式会议 1.当天站立式会议照片一张 2.团队成员报告 林楚虹 (1) 昨天已完成的工作:导入到数据表 (2) 今天计划完成的工作:排行榜功能 (3) 工作中遇到的困难:转为csv文件时音标 ...