洛谷 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]病毒 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已 ...
随机推荐
- BootStrap学习(7)_轮播图
一.轮播图 Bootstrap 轮播(Carousel)插件是一种灵活的响应式的向站点添加滑块的方式.除此之外,内容也是足够灵活的,可以是图像.内嵌框架.视频或者其他您想要放置的任何类型的内容. 如果 ...
- CF 799B T-shirt buying
一道超级水的练习STL的题目 题目大意:有\(n\)件T恤,每件T恤都分别有价格(每件衣服的价格不重复).前面的颜色.背部的颜色三种属性.接下来有\(m\)个人每个人都有一种喜欢的颜色,他们按先后顺序 ...
- Oracle 社区动态、中文讲座,最佳实践
https://community.oracle.com/thread/3789691https://community.oracle.com/community/support/%E4%B8%AD% ...
- 面试4——java进程和线程相关知识
1.线程和进程的概念.并行和并发的概念
- ssh实现办公室电脑连接家中的电脑
友情提示:如果您不知道您家路由器管理页面的密码,请您忽略此文. 问题背景: 家中有台笔记本电脑,它是通过家中的路由器与外界联网的,这时,我想通过ssh服务让公司的电脑能连上我家中的笔记本. 可以画个图 ...
- Heartbeat基础知识-运维小结
在日常的集群系统架构中,一般用到Heartbeat的主要就2种:1)高可用(High Availability)HA集群, 使用Heartbeat实现,也称为”双机热备”, “双机互备”, “双机”: ...
- Python 可调用对象
除了用户定义的函数,调用运算符(即 ())还可以应用到其他对象上.如果想判断对象能否调用,可以使用内置的 callable() 函数.Python 数据模型文档列出了 7 种可调用对象.(1)用户定义 ...
- Selenium IDE 宏 试用 一例
本质是宏(Macro)理念 Marco概念的广泛应用: 1.Office的Excel里的任何操作的 可以都可以用VBA编程记录下宏,然后把记录的宏,可以回放.当然也可以生成代码,比如给Excel设置单 ...
- [转帖]Intel新一代Xeon完整曝光
AMD已经官宣7nm工艺的第二代EPYC霄龙服务器平台,今年上半年就会大规模出货,而在Intel这边,由于10nm工艺进展还是不够快,在服务器上还是需要14nm继续打天下,而且还有两代14nm工艺产品 ...
- 使用 py.test 对 python 代码进行测试
其实以前我记得有人对我说过,写代码甚至可以先写完测试之后部署好了再开始写逻辑代码.我觉得有点吃惊和奇怪,这不是扯淡吗? 但是这次在完成了积分支付第一阶段开发之后我意识到,这可能并不是开玩笑,特别是项目 ...