洛谷 P1054等价表达式题解--zhengjun
题目描述
明明进了中学之后,学到了代数表达式。有一天,他碰到一个很麻烦的选择题。这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的。
这个题目手算很麻烦,因为明明对计算机编程很感兴趣,所以他想是不是可以用计算机来解决这个问题。假设你是明明,能完成这个任务吗?
这个选择题中的每个表达式都满足下面的性质:
表达式只可能包含一个变量‘’。
表达式中出现的数都是正整数,而且都小于。
表达式中可以包括四种运算(加),(减),(乘),^ (乘幂),以及小括号,。小括号的优先级最高,其次是^ ,然后是,最后是和。和的优先级是相同的。相同优先级的运算从左到右进行。(注意:运算符,,,^ 以及小括号,都是英文字符)
幂指数只可能是到之间的正整数(包括和)。
表达式内部,头部或者尾部都可能有一些多余的空格。
下面是一些合理的表达式的例子:
((a^1) ^ 2)^3,a*a+a-a,((a+a)),9999+(a-a)*a,1 + (a -1)^3,1^10^9………
输入格式
第一行给出的是题干中的表达式。
第二行是一个整数,表示选项的个数。后面行,每行包括一个选项中的表达式。这个选项的标号分别是
输入中的表达式的长度都不超过个字符,而且保证选项中总有表达式和题干中的表达式是等价的。
输出格式
一行,包括一系列选项的标号,表示哪些选项是和题干中的表达式等价的。选项的标号按照字母顺序排列,而且之间没有空格。
输入输出样例
输入 #1 复制
( a + 1) ^2
3
(a-1)^2+4*a
a + 1+ a
a^2 + 2 * a * 1 + 1^2 + 10 -10 +a -a
输出 #1 复制
AC
说明/提示
对于的数据,表达式中只可能出现两种运算符和;
对于其它的数据,四种运算符,,,^ 在表达式中都可能出现。
对于全部的数据,表达式中都可能出现小括号和。
年提高组第四题
思路
特别想吐槽一下这道题
数据又特别水,值还很大,题目中没说表达式的括号一定匹配,所以要判断,我无语了
首先,我判断两个表达式相等的依据就是代入不同的值,如果结果都一样,那么这两个表达式就是等价的。如果还没有学过表达式求值的话,建议先去看看栈的实现。
然后,这道题的数据水到什么程度,我代特值,只要代一个,就可以得到分,然后,代两个就满分了,我谔谔,答案还特别大,需要取模,告诉你我取模是靠传说中的,真香。
代码
#include<bits/stdc++.h>
using namespace std;
int mod;
/********以下是表达式求值********/
map<char,int> p;
int a[1001],aa,bb;
char b[1001];
void init(){
p['+']=1;
p['-']=1;
p['*']=2;
p['/']=2;
p['^']=3;
p['(']=0;
p[')']=0;
p['=']=-1;
}
int pow(int x,int y){//快速幂,不然TEL
int ans=1,cnt=x;
while(y){
if(y&1)ans=ans*cnt%mod;
cnt=cnt*cnt%mod;
y>>=1;
}
return ans;
}
void js(){
char s=b[bb--];
int x=a[aa--],y=a[aa--],z;
switch(s){
case '+':{z=y+x;z%=mod;break;}
case '-':{z=y-x;z%=mod;break;}
case '*':{z=y*x;z%=mod;break;}
case '/':{z=y/x;z%=mod;break;}
case '^':{z=pow(y,x);z%=mod;break;}
}
a[++aa]=z;
}
int get(string s,int k){
int len,i=0;
s+='=';
len=s.length();
aa=bb=0;
while(i<len){
if(s[i]==' '){i++;continue;}
if(s[i]=='a'){a[++aa]=k;i++;continue;}
if(s[i]>='0'&&s[i]<='9'){
int x=s[i++]-'0';
while(s[i]>='0'&&s[i]<='9')x=x*10+s[i++]-'0';
a[++aa]=x;
continue;
}
if(s[i]=='('){b[++bb]=s[i++];continue;}
while(bb>0&&p[s[i]]<=p[b[bb]]){
if(s[i]==')'&&b[bb]=='('){bb--;break;}
js();
}
if(s[i]!=')')b[++bb]=s[i];
i++;
}
return a[1];
}
/********以上是表达式求值********/
bool check(string s){//判断括号匹配
int top=0,len=s.length();
for(int i=0;i<len;i++){
if(s[i]=='(')top++;
if(s[i]==')')top--;
if(top<0)return 0;
}
return top==0;
}
int main(){
init();
srand(time(0));
mod=rand()%50000+100;//精髓
int n;
string s;
getline(cin,s);
int x[5];
for(int i=1;i<4;i++)x[i]=get(s,i);
scanf("%d\n",&n);//要过滤一个换行
string ans;
for(int i=1;i<=n;i++){
getline(cin,s);
if(!check(s))continue;
int j;
for(j=1;j<4;j++)if(get(s,j)!=x[j])break;
if(j==4)ans+=char('A'+i-1);
}
cout<<ans;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人