题目描述
明明进了中学之后,学到了代数表达式。有一天,他碰到一个很麻烦的选择题。这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的。
这个题目手算很麻烦,因为明明对计算机编程很感兴趣,所以他想是不是可以用计算机来解决这个问题。假设你是明明,能完成这个任务吗?
这个选择题中的每个表达式都满足下面的性质:
1. 表达式只可能包含一个变量‘a’。
2. 表达式中出现的数都是正整数,而且都小于10000。
3. 表达式中可以包括四种运算‘+’(加),‘-’(减),‘*’(乘),‘^’(乘幂),以及小括号‘(’,‘)’。小括号的优先级最高,其次是‘^’,然后是‘*’,最后是‘+’和‘-’。‘+’和‘-’的优先级是相同的。相同优先级的运算从左到右进行。(注意:运算符‘+’,‘-’,‘*’,‘^’以及小括号‘(’,‘)’都是英文字符)
4. 幂指数只可能是1到10之间的正整数(包括1和10)。
5. 表达式内部,头部或者尾部都可能有一些多余的空格。
下面是一些合理的表达式的例子:
((a^1) ^ 2)^3,a*a+a-a,((a+a)),9999+(a-a)*a,1 + (a -1)^3,1^10^9……
输入输出格式
输入格式:
输入文件equal.in的第一行给出的是题干中的表达式。第二行是一个整数n(2 <= n <= 26),表示选项的个数。后面n行,每行包括一个选项中的表达式。这n个选项的标号分别是A,B,C,D……
输入中的表达式的长度都不超过50个字符,而且保证选项中总有表达式和题干中的表达式是等价的。
输出格式:
输出文件equal.out包括一行,这一行包括一系列选项的标号,表示哪些选项是和题干中的表达式等价的。选项的标号按照字母顺序排列,而且之间没有空格。
输入输出样例
( a + 1) ^2 3 (a-1)^2+4*a a + 1+ a a^2 + 2 * a * 1 + 1^2 + 10 -10 +a -a
AC
说明
对于30%的数据,表达式中只可能出现两种运算符‘+’和‘-’;
对于其它的数据,四种运算符‘+’,‘-’,‘*’,‘^’在表达式中都可能出现。
对于全部的数据,表达式中都可能出现小括号‘(’和‘)’。
2005年提高组第四题
熬夜刷题浪费青春系列。
从22:30开始做,本来大概23:30的时候就应该做出来了,因为判断函数写反多调了30分钟,又因为忘了开long long多调了30+分钟……
嗨呀好气呀!
如果没有这个变量,是经典的stack后缀表达式计算应用题。
有了变量怎么办?枚举十几个不同的数带入进去算,如果要比较的两个式子返回结果都一样,那么两式相同。
1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<vector> 8 using namespace std; 9 const long long mod=1e11+7; 10 const int mxn=10010; 11 int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 14 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 15 return x*f; 16 } 17 string s1,s2; 18 char st[mxn];int top=0; 19 long long num[mxn];int ntop=0; 20 int cmp(char ch){ 21 if(!top || st[top]=='(') return 0; 22 if(st[top]=='^') return 1; 23 if(ch=='^') return 0; 24 if(st[top]=='*') return 1; 25 if(ch=='*') return 0; 26 return 1; 27 } 28 int pp(){ 29 switch(st[top]){ 30 case '(':{ 31 top--; 32 return 1; 33 break; 34 } 35 case '+':{ 36 long long n1=num[ntop--]; 37 long long n2=num[ntop--]; 38 num[++ntop]=n1+n2; 39 break; 40 } 41 case '-':{ 42 long long n1=num[ntop--]; 43 long long n2=num[ntop--]; 44 num[++ntop]=n2-n1; 45 break; 46 } 47 case '*':{ 48 long long n1=num[ntop--]; 49 long long n2=num[ntop--]; 50 num[++ntop]=n2*n1; 51 break; 52 } 53 case '^':{ 54 long long n1=num[ntop--]; 55 long long n2=num[ntop--]; 56 // num[++ntop]=pow(n2,n1); 57 long long bas=1; 58 for(int j=1;j<=n1;j++)bas=(bas*n2); 59 num[++ntop]=bas; 60 break; 61 } 62 } 63 top--; 64 return 0; 65 } 66 long long clc(string s,int tp){ 67 top=ntop=0; 68 memset(num,0,sizeof num); 69 memset(st,0,sizeof st); 70 int len=s.length(); 71 int i,j; 72 for(i=0;i<len;i++){ 73 if(s[i]==' ')continue; 74 if(s[i]=='('){ 75 st[++top]='('; 76 continue; 77 } 78 if(s[i]=='a'){ 79 num[++ntop]=tp; 80 continue; 81 } 82 if(s[i]>='0' && s[i]<='9') 83 { 84 int x=0; 85 while(s[i]>='0' && s[i]<='9'){ 86 x=x*10+s[i]-'0'; 87 i++; 88 } 89 i--; 90 num[++ntop]=x; 91 continue; 92 } 93 if(s[i]==')'){ 94 if(top==1 && i!=len-1)i++; 95 while(1){if(pp())break;} 96 continue; 97 } 98 while(cmp(s[i]))pp(); 99 st[++top]=s[i]; 100 } 101 102 while(top>0){pp();} 103 // printf("%lld\n",num[1]); 104 return num[1]; 105 } 106 int n; 107 int main(){ 108 int i,j; 109 getline(cin,s1); 110 s1='('+s1+')'; 111 112 scanf("%d",&n); 113 getline(cin,s2);//读空行 114 for(i=0;i<n;++i){ 115 getline(cin,s2); 116 s2='('+s2+')'; 117 bool flag=1; 118 for(j=5;j<=11;j++){ 119 if(clc(s1,j*7+3)!=clc(s2,j*7+3)){ 120 flag=0; 121 break; 122 } 123 } 124 if(flag)printf("%c",i+'A'); 125 } 126 return 0; 127 }