【解题报告】zju-1145 Dreisam Equations
原题地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=145
题目大意:在给定的等式右边数字之间加上加、减、乘运算符,使等式成立。
解题思路:遍历每一种情况,有计算式子的结果,若等于左边的数字,则输出答案。
题目输入的几点:
所给的式子左边是一个数字,然后是一个等号,之间可能有空格,也可能没有。然后右边的式子每两个数字之间至少有一个空格或者括号,以便区分,因此,两个数字之间可能没有空格只有括号。所以先处理右边的式子的字符串:
先定义一个新的字符串s
1.消除前置空格
2.根据字符串开头到第一个数字之间的括号数,s放入相应的前括号
3.s放入相应的数字
4.在每两个数字之间,分别计数前括号,后括号的个数,然后s依次放入对应个数的后括号、一个空格、相应的前括号
最后新的字符串s就是处理后的字符串,这个字符串满足,每两个数字之间有一个空格,且这个空格在后括号后面,前括号前面。如字符串:"(1 1)(1 1)"就会变成:"(1 1) (1 1)"在第二个“1”和第三个“1”之间有三个字符,分别是‘)’、‘ ’(空格)、‘(’。而第一个数字之前没有多余的空格,最后一个数字之后也没有多余的空格。
这样,问题就变成在给定的字符串中的空格处填入运算符,计算结果。
计算过程中用到了递归操作,每对括号内都是一个子字符串,且格式相同,将括号内的字符串进行递归可以得到整个括号内的表达式的值。
解题代码:
1 #include<stdio.h> 2 #include<iostream> 3 #include<string.h> 4 using namespace std; 5 int q(char *s,char *send) 6 { 7 char s1[5]; 8 int ans=0; 9 char fuhao=*(s-1); 10 if(fuhao!='+'&&fuhao!='-'&&fuhao!='*') fuhao='+'; 11 while(s<=send) 12 { 13 fuhao=*(s-1); 14 if(fuhao!='+'&&fuhao!='-'&&fuhao!='*') fuhao='+'; 15 if(*s=='(') 16 { 17 int n=1; 18 char *ss=s; 19 while(n) 20 { 21 ss++; 22 if(*ss=='(') n++; 23 if(*ss==')') n--; 24 } 25 switch(fuhao) 26 { 27 case '+':ans+=q(s+1,ss-1);break; 28 case '-':ans-=q(s+1,ss-1);break; 29 case '*':ans*=q(s+1,ss-1);break; 30 } 31 s=ss+2; 32 } 33 else 34 { 35 int as; 36 sscanf(s,"%[0-9]",s1); 37 sscanf(s1,"%d",&as); 38 switch(fuhao) 39 { 40 case '+':ans+=as;break; 41 case '-':ans-=as;break; 42 case '*':ans*=as;break; 43 } 44 while((*s!='+'&&*s!='-'&&*s!='*')&&s<=send) s++; 45 s++; 46 } 47 } 48 return ans; 49 } 50 char s[100]; 51 int t; 52 int DFS(char *ss) 53 { 54 char *sss=ss+1; 55 if(*ss==0) 56 { 57 int ans=q(s,s+strlen(s)-1); 58 if(ans==t) 59 { 60 return 0; 61 } 62 return 1; 63 } 64 while(*sss!=' '&&*sss!=0) sss++; 65 *ss='+'; 66 if(!DFS(sss)) return 0; 67 *ss='-'; 68 if(!DFS(sss)) return 0; 69 *ss='*'; 70 if(!DFS(sss)) return 0; 71 *ss=' '; 72 return 1; 73 } 74 void strccc(char c[]) 75 { 76 int i=0,z=0,k=1,x=0; 77 char s[100]; 78 s[0]=0; 79 while(c[i]==' ') i++; 80 while(1) 81 { 82 z=x=0; 83 while(!(c[i]<='9'&&c[i]>='0'||c[i]==0)) 84 { 85 if(c[i]=='(') z++; 86 if(c[i]==')') x++; 87 i++; 88 } 89 if(c[i]==0) k=2; 90 if(x>0) 91 while(x--) strcat(s,")"); 92 if(k==0) strcat(s," "); 93 if(z>0) 94 while(z--) strcat(s,"("); 95 if(k==2) break; 96 while(c[i]<='9'&&c[i]>='0') {int len=strlen(s);s[len]=c[i];s[len+1]=0;i++;} 97 k=0; 98 } 99 strcpy(c,s); 100 } 101 int main() 102 { 103 int k=1,i,j; 104 while(cin>>t,t) 105 { 106 while(getchar()!='=') ; 107 gets(s); 108 strccc(s);//处理 109 char *ss=s; 110 while(*ss!=' '&&*ss!=0) ss++; 111 cout<<"Equation #"<<k++<<":"<<endl; 112 if(DFS(ss)) cout<<"Impossible"<<endl; 113 else cout<<t<<"="<<s<<endl; 114 cout<<endl; 115 } 116 return 0; 117 }