这题是@laybxc这位神犇推荐给我写的。从开始写到AC前后时间跨度一个星期,这是我第一次认认真真写高精,100+的总提交次数应该有15次是我提交的,因为实在太毒瘤了,感谢@laybxc提供的高精度模板让我找出了原本我写的代码中的错误,今天终于AC了,所以发一篇题解庆祝一下。


这道题本质是道模拟题(第一次看的时候还是黄题,现在居然蓝了),主要做法就是遍历字符串并找出每一项的值,然后加起来,用int可以过60分,long long和int128也都只能过60分,显然剩下40分必须用高精了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
//因为我太弱了,不会写高精度类,只会用struct
//而且写高精度算法的经验比较少,所以高精写的比较丑
struct BigInt
{
int ch;
int x[300];
};
inline void clear(BigInt& x); //初始化BigInt
inline BigInt read(); //读入BigInt(好像这题并没有用)
inline int Compare(BigInt a, BigInt b);//比较函数
inline BigInt Plus(BigInt a, BigInt b);//高精加
inline BigInt Minus(BigInt a, BigInt b);//高精减
inline BigInt Multi(BigInt a, BigInt b);//高精乘
inline BigInt Int_to_BigInt(int x);//把int转换成BigInt
inline void clear(BigInt& x)
{
memset(x.x, 0, sizeof(x.x));
x.ch = 1;
}
inline BigInt read()
{
BigInt x;
clear(x);
char ch = getchar();
while(!isdigit(ch) && ch != '-')
ch = getchar();
if(ch == '-')
{
x.ch = -1;
ch = getchar();
}
while(isdigit(ch))
{
x.x[++x.x[0]] = ch - '0';
ch = getchar();
}
for(int i=1; i<=x.x[0]/2; i++)
{
swap(x.x[i], x.x[x.x[0]-i+1]);
}
return x;
}
inline BigInt Int_to_BigInt(int x)
{
BigInt c;
clear(c);
if(x < 0)
{
c.ch = -1;
x = -x;
}
if(x == 0) c.x[0]++;
while(x)
{
c.x[++c.x[0]] = x % 10;
x /= 10;
}
return c;
}
inline int Compare(BigInt a, BigInt b)
{
if(a.x[0] > b.x[0]) return 1;
if(a.x[0] < b.x[0]) return -1;
for(int i=a.x[0]; i; i--)
{
if(a.x[i] > b.x[i]) return 1;
if(a.x[i] < b.x[i]) return -1;
}
return 0;
}
inline BigInt Plus(BigInt a, BigInt b)
{
BigInt c;
clear(c);
if(a.ch == 1 && b.ch == -1)
{
b.ch = 1;
return Minus(a, b);
}
if(a.ch == -1 && b.ch == 1)
{
a.ch = 1;
return Minus(b, a);
}
if(a.ch == -1 && b.ch == -1)
{
c.ch = -1;
}
int k = a.x[0] > b.x[0] ? a.x[0] : b.x[0], g = 0;
for(int i=1; i<=k; i++)
{
c.x[i] = a.x[i] + b.x[i] + g;
g = c.x[i] / 10;
c.x[i] %= 10;
}
if(g) c.x[++k] = g;
c.x[0] = k;
return c;
}
inline BigInt Minus(BigInt a, BigInt b)
{
BigInt c;
clear(c);
if(a.ch == -1 && b.ch == -1)
{
a.ch = 1;
b.ch = 1;
return Minus(b, a);
}
if(a.ch == -1 && b.ch == 1)
{
a.ch = 1;
c = Plus(a, b);
c.ch = -1;
return c;
}
if(a.ch == 1 && b.ch == -1)
{
b.ch = 1;
return Plus(a, b);
}
int flag = Compare(a, b);
if(flag == 0)
{
c.x[0] = 1;
return c;
}
if(flag == 1)
{
int k = a.x[0];
for(int i=1; i<=k; i++)
{
if(a.x[i] < b.x[i])
{
a.x[i+1]--;
a.x[i] += 10;
}
c.x[i] = a.x[i] - b.x[i];
}
while(c.x[k] == 0) k--;
c.x[0] = k;
return c;
}
else
{
int k = b.x[0];
c.ch = -1;
for(int i=1; i<=k; i++)
{
if(b.x[i] < a.x[i])
{
b.x[i+1]--;
b.x[i] += 10;
}
c.x[i] = b.x[i] - a.x[i];
}
while(c.x[k] == 0) k--;
c.x[0] = k;
return c;
}
}
inline BigInt Multi(BigInt a, BigInt b)
{
BigInt c;
clear(c);
c.ch = a.ch * b.ch;
int ka = a.x[0], kb = b.x[0], k = ka + kb + 1;
for(int i=1; i<=ka; i++)
{
for(int j=1; j<=kb; j++)
{
c.x[i+j-1] += a.x[i] * b.x[j];
c.x[i+j] += c.x[i+j-1] / 10;
c.x[i+j-1] %= 10;
}
}
while(!c.x[k]) k--;
c.x[0] = k;
return c;
}
inline void print(BigInt x)//打印高精度数
{
if(x.x[0] == 0) printf("0");
if(x.ch == -1) printf("-");
for(int i=1; i<=x.x[0]; i++)
printf("%d", x.x[x.x[0]-i+1]);
}
const int maxn = 205;
int top, len;
int b[maxn];
BigInt ansx, ans[maxn], tmp;
char a[maxn];
int main()
{
clear(ansx);
ansx.x[0] = 1;
scanf("%s", a+1);
len = strlen(a+1);
for(int i=1; i<=len; i++)
{
if(i == 1 && (a[i] >= '0' && a[i] <= '9'))
{ //如果第一个字符属于第一个数,则直接存起来
int l, r;
for(l=1; l<=len; l++)
{
if(a[l] < '0' || a[l] > '9')
{
r = l-1;
break;
}
}
++top;
clear(ans[top]);
ans[top] = Plus(ans[top], Int_to_BigInt(a[1] - '0'));
for(int j=2; j<=r; j++)
{
clear(tmp);
ans[top] = Multi(ans[top], Int_to_BigInt(10));
ans[top] = Plus(ans[top], Int_to_BigInt(a[j]-'0'));
}
continue;
}
if(a[i] == '+' || a[i] == '-')
{ //遇到'+'号或'-'号就处理这一项的值
char character;
character = a[i];
int m, k, l;
BigInt ax, bx, numc;
clear(ax);
clear(bx);
clear(numc);
for(int j=i; j<=len; j++)
{ //找出'+'号或'-'号的个数
if(a[j] != character)
{
m = j - 1;
break;
}
numc = Plus(numc, Int_to_BigInt(1));
}
if(a[m+1] == '(')
{ //处理括号内的数的值
for(int j=m+2; j<=len; j++)
{
if(a[j] == ')')
{
k = j-1;
break;
}
}
ax = Plus(ax, Int_to_BigInt(a[m+2] - '0'));
for(int j=m+3; j<=k; j++)
{
ax = Multi(ax, Int_to_BigInt(10));
ax = Plus(ax, Int_to_BigInt(a[j] - '0'));
}
}
else
{
k = m - 1;
ax = Plus(Int_to_BigInt(0), Int_to_BigInt(1));
               //如果并没有括号则 ax = 1;
}
for(int j=k+2; j<=len; j++)
{ //处理此项剩余部分的值
if(j == len) l = j;
if(a[j] < '0' || a[j] > '9')
{
l = j-1;
break;
}
}
bx = Plus(bx, Int_to_BigInt(a[k+2] - '0'));
for(int j=k+3; j<=l; j++)
{
bx = Multi(bx, Int_to_BigInt(10));
bx = Plus(bx, Int_to_BigInt(a[j] - '0'));
}
++top;
clear(ans[top]);
ans[top] = Plus(Int_to_BigInt(0), Int_to_BigInt(1));
ans[top] = Multi(ans[top], ax);
ans[top] = Multi(ans[top], bx);
ans[top] = Multi(ans[top], numc);
//把符号个数,括号内的数,后的数的值乘起来
i = l;
if(character == '-')//如果是'-'号则项取相反数
ans[top] = Multi(ans[top], Int_to_BigInt(-1));
}
}
for(int i=1; i<=top; i++) //把每一项的数加起来作为答案输出
ansx = Plus(ansx, ans[i]);
print(ansx);
return 0;
}