洛谷 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,1^10^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 解题报告的更多相关文章
- 洛谷 P1462 解题报告
P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...
- 洛谷 P1879 解题报告
P1879 [USACO06NOV]玉米田Corn Fields 题目描述 农场主\(John\)新买了一块长方形的新牧场,这块牧场被划分成\(M\)行\(N\)列\((1 ≤ M ≤ 12; 1 ≤ ...
- 洛谷 P1069 解题报告
P1069 细胞分裂 题目描述 \(Hanks\)博士是\(BT\) (\(Bio-Tech\),生物技术) 领域的知名专家.现在,他正在为一个细胞实验做准备工作:培养细胞样本. \(Hanks\) ...
- 洛谷 P2491 解题报告
P2491 消防 题目描述 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情,所以这个 ...
- 洛谷 P2587 解题报告
P2587 [ZJOI2008]泡泡堂 题目描述 第XXXX届NOI期间,为了加强各省选手之间的交流,组委会决定组织一场省际电子竞技大赛,每一个省的代表队由n名选手组成,比赛的项目是老少咸宜的网络游戏 ...
- 洛谷 P1053 解题报告
P1053 篝火晚会 题目描述 佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了"小教官".在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会.一共有 ...
- 洛谷 P1057 解题报告
P1057 传球游戏 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹 ...
- 洛谷 P1430 解题报告
P1430 序列取数 题目描述 给定一个长为\(n\)的整数序列\((n<=1000)\),由\(A\)和\(B\)轮流取数(\(A\)先取).每个人可从序列的左端或右端取若干个数(至少一个), ...
- 洛谷 P1613 解题报告
P1613 跑路 题目描述 小\(A\)的工作不仅繁琐,更有苛刻的规定,要求小\(A\)每天早上在\(6:00\)之前到达公司,否则这个月工资清零.可是小\(A\)偏偏又有赖床的坏毛病.于是为了保住自 ...
随机推荐
- (NO.00001)iOS游戏SpeedBoy Lite成形记(二十三)
现在还有一个视觉上的问题:玩家每次在游戏开始前选择某一赛道时,无法直观的看到所选的是哪条赛道.只能通过界面上方的gambleLabel中的文字非直观的看到.我们现在来完善它! 为了能让玩家清楚地看到, ...
- markdown简易快速的编辑格式(易读易写)
实现简单快速书写,格式指定简便.易读易写 讲解http://wowubuntu.com/markdown/ 简单使用的讲解:http://www.ituring.com.cn/article/23 代 ...
- 网络小白之WAN与LAN的区别
剑指Offer--网络小白之WAN与LAN的区别 基本作用 wan接口是外网接口,是用来连接互联网或局域网等外部网络的. lan接口是内网接口,是用来连接计算机终端或其他路由器等终端设备的. 举例 w ...
- Android源码浅析(一)——VMware Workstation Pro和Ubuntu Kylin 16.04 LTS安装配置
Android源码浅析(一)--VMware Workstation Pro和Ubuntu Kylin 16.04 LTS安装配置 最近地方工作,就是接触源码的东西了,所以好东西还是要分享,系列开了这 ...
- 【算法导论】八皇后问题的算法实现(C、MATLAB、Python版)
八皇后问题是一道经典的回溯问题.问题描述如下:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8*8个方格),使它们谁也不能被吃掉? 看到这个问题,最容易想 ...
- android采用SurfaceView实现文字滚动效果
前言 为了实现文字的滚动效果,之前也重写了TextView效果都不太好,后来对SurfaceView进行完善. 声明 欢迎转载,但请保留文章原始出处:) 小崔博客:http://blog.c ...
- Android使用SVG矢量动画(二)
上篇我们学习了怎么显示SVG矢量图像,当然还有一个更强大的功能,就是让SVG图像动起来,先上一张效果图吧: 要实现上述动画效果,就得用AnimatedVectorDrawable这个类了,它就是负责V ...
- adb shell后出现error解决方案
解决办法: 解决办法: 1.adb kill-server 2.adb start-server 3.adb remount 4.adb shell 一般情况下都可以在此启动adb相关
- AngularJS进阶(八)实现页面跳转并进行参数传递
angularjs实现页面跳转并进行参数传递 注:请点击此处进行充电! Angular页面传参有多种办法,我在此列举4种最常见的: 1. 基于ui-router的页面跳转传参 (1) 在Angular ...
- LeetCode之“数组”:Rotate Array
题目链接 题目要求: Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, ...