ZOJ Problem Set - 1014

Operand

Time Limit: 1 Second      Memory Limit: 32768 KB

Professor Maple teaches mathematics in a university. He have invented a function for the purpose of obtaining the operands from an expression. The function named op(i,e) can be described as follows:

The expression e may be divided into sub-expression(s) by the operator, which has the lowest priority in the expression. For example, the expression "a*b+b*c+c*d" should be divided into three sub-expressions "a*b", "b*c" and "c*d", because the operator "+" has the lowest priority. The purpose of this function is to extract the ith sub-expression as the result. So, in the example above, op(2,e)=b*c.


If we regard the sub-expression as the main expression, it might be divided again and again. Obviously, the dividing process is recursive. As you see, the following example is much more complex:

Let p:=a^b*c+(d*c)^f*z+b
op(1,op(1,op(2,p)))=(d*c)
op(1,op(1,op(1,op(2,p))))=d*c
op(2,op(2,p))=z
op(3,p)=b
op(1,op(3,p))=b

Professor Maple is so lazy that he would leave the work to computer rather than do it himself, when the expression is long and complicated. Of course, without your program, the computer won't work out the result automatically.


Input

The input file contains several test cases. The last test case in the input file is followed by a line containing a symbol "*", indicating the end of the input data. Each test case consists of two parts. The first part describes the expression, while the second part contains several questions, which should be calculated according to the expression.

The first line of each test case contains an expression consists of the expression name, ":=" and the content of the expression. The expression name is a lowercase. And the content is composed by lowercases and operators "+", "(", ")", "*" and "^". For example, here is a valid expression, p:=a^b*c+(d*c)^f*z+b. Among those operators, "(" and ")" have the highest priority. The operator "^" has a lower priority, and then "*". The priority of the operator "+" is the lowest.

The second line of each test case contains an integer n indicating n questions based on the above expression. This is followed by n lines. Each of them contains the description of one question, which consists of integers. For example, the question with three integers "2 1 1" describes the function op(1,op(1,op(2,e))). To compute this function, we have to keep to the following sequence: First, according to the first integer 2, divide the expression and extract the 2nd sub-expression. Then, according to the second integer 1, divide the sub-expression and extract the 1st one. Finally, according to the third integer 1, divide the outcome again, and extract the result.


Output

For each test case, display the expression name and a colon on the first line. Then display the result of each question on a line. The layout of the output is shown in the sample output.

You may assume that all expressions and functions are always valid.
Display a blank line between test cases.


Sample Input

p:=a^b*c+(d*c)^f*z+b
4
2 1 1
2 2
3
3 1
a:=(x+y)
3
1
1 2
1 2 1
*


Output for the Sample Input

Expression p:
op(1,op(1,op(2,p)))=(d*c)
op(2,op(2,p))=z
op(3,p)=b
op(1,op(3,p))=b

Expression a:
op(1,a)=x+y
op(2,op(1,a))=y
op(1,op(2,op(1,a)))=y

 

1 #include <stdio.h>
2
3  #define MAXEXPRESSION 100000
4  #define MAXDIVISION 1000
5
6 char EXPRESSION_NAME, EXPRESSION[MAXEXPRESSION], RESULT[MAXEXPRESSION];
7 int DIVISION[MAXDIVISION], N, DIVISION_TMES;
8
9 int JUMP_BRACKET(char expression[], int i)/* expression[i] == '(' */
10 {
11 int left_bracket = 1, right_bracket = 0;
12 while(1)
13 {
14 i++;
15 if(expression[i] == '(') left_bracket ++;
16 else if(expression[i] == ')')
17 {
18 right_bracket ++;
19 if(left_bracket == right_bracket)
20 return i+1;/* ')' 的下一字符位置 */
21 }
22 }
23 }
24
25 char GET_LOWEST_OPERATOR(char expression[])
26 {
27 char lowest_operator = 0;
28 int i;
29 if(expression[0] == '(')/* 全被括起 */
30 {
31 i = JUMP_BRACKET(expression, 0);
32 if(( expression[i]) == 0)
33 return -(i-2);
34 }
35 for(i=0; expression[i] != 0; i++)
36 {
37 if(expression[i] == '(')/* 跳括号 */
38 i = JUMP_BRACKET(expression, i) - 1;
39 else if(expression[i] == '+') return '+';
40 else if(expression[i] == '*')
41 lowest_operator = '*';
42 else if(expression[i] == '^' && lowest_operator != '*')
43 lowest_operator = '^';
44 }
45 return lowest_operator;
46 }
47 void GET_RESULT(char final_expression[])
48 {
49 int i;
50 for(i=0; final_expression[i]!=0; i++)
51 RESULT[i] = final_expression[i];
52 RESULT[i] = 0;
53 }
54 int COPY(char cur_expression[], int i, char pre_expression[], int n, int m)/* 返回cur_expression[]待写入的位置 */
55 {
56 for(; n<=m; n++,i++)
57 cur_expression[i] = pre_expression[n];
58 cur_expression[i] = 0;
59 return i;
60 }
61 void PROCEED(int div_num, char pre_expression[]) /* 无回溯的递归式字符串处理 */
62 {
63 char cur_expression[MAXEXPRESSION];
64 char lowest_operator;
65 int i, j, k, expression_num;
66 if(div_num == DIVISION_TMES)/* 已分割完毕 */
67 {
68 GET_RESULT(pre_expression);
69 return;
70 }
71 lowest_operator = GET_LOWEST_OPERATOR(pre_expression);
72 if(lowest_operator == 0)/* 没有运算符了,表达式也没被括起(即无法再分)*/
73 {
74 GET_RESULT(pre_expression);
75 return;
76 }
77 if(lowest_operator < 0)/* 表达式被括起,只需去括号即可进入下一层 */
78 {
79 COPY(cur_expression, 0, pre_expression, 1, -lowest_operator);
80 PROCEED(div_num+1, cur_expression);
81 return;
82 }
83 expression_num = 0;
84 for(i=0; ; i++)/* 当前要取第n部分,n>=1 */
85 {
86 if(pre_expression[i] == lowest_operator)
87 {
88 expression_num ++;
89 i++;
90 }
91 if(expression_num == DIVISION[div_num] - 1)
92 {
93 j=0;
94 while(1)
95 {
96 if(pre_expression[i] == '(')/* 吸收括号 */
97 {
98 k = JUMP_BRACKET(pre_expression, i);
99 j = COPY(cur_expression, j, pre_expression, i, k-1);
100 i = k;
101 }
102 if(pre_expression[i] == lowest_operator || pre_expression[i] == 0)
103 {
104 cur_expression[j] = 0;
105 PROCEED(div_num+1, cur_expression);
106 return;
107 }
108 cur_expression[j] = pre_expression[i];
109 j++;
110 i++;
111 }
112 }
113 if(pre_expression[i] == '(')/* 跳括号 */
114 i = JUMP_BRACKET(pre_expression, i) - 1;
115 }
116 }
117 int main()
118 {
119 int i, j, count = 0;
120 while((EXPRESSION_NAME = getchar()) != '*')
121 {
122 getchar();
123 getchar();
124 count ++;
125 if(count > 1) putchar(10);
126 printf("Expression %c:\n", EXPRESSION_NAME);
127 scanf("%s", EXPRESSION);
128 scanf("%d", &N);
129 for(i=0; i<N; i++)
130 {
131 for(j=0; ; j++)
132 {
133 scanf("%d", &DIVISION[j]);
134 if(getchar() == 10)
135 {
136 DIVISION_TMES = j + 1;
137 break;
138 }
139 }
140 PROCEED(0, EXPRESSION);
141 for(j=DIVISION_TMES-1; j>=0; j--)
142 printf("op(%d,", DIVISION[j]);
143 printf("%c", EXPRESSION_NAME);
144 for(j=DIVISION_TMES-1; j>=0; j--)
145 printf(")");
146 printf("=%s\n", RESULT);
147 }
148 }
149 }

 

 

做了一天一夜,把AC率下调了10%

无论如何,我是不会放弃的。

posted @ 2010-05-01 11:28  长江西岸  阅读(601)  评论(0编辑  收藏  举报