1 #include<stdio.h>
2 #include<string.h>
3 #include<conio.h>
4 #include<stdlib.h>
5 #include<time.h>
6 #define N 1000
7 // 大数模板。。。
8 class BigNum
9 {
10 public:
11 int s[N]; //存放各位数字,s[0]为符号位,1代表正数,-1代表负数
12 //数组内高位存高位,123存在里面则为 1 3 2 1 ,第1个 1表示符号
13 int len; //长度
14 public:
15 BigNum()
16 {
17 memset(s,0,sizeof(s)); //初始化全0
18 s[0]=1; //默认正数
19 len=2; //变量初始化为0
20 }
21 int in() //输入
22 {
23 char tmp[N];
24 int flag=scanf("%s",tmp);
25 *this=tmp;
26 return flag;
27 }
28 void out() //输出
29 {
30 if(s[0]==-1) printf("-");
31 for(int i=len-1;i>0;i--)
32 printf("%d",s[i]);
33 }
34 void Clear()
35 {
36 memset(s,0,sizeof(s)); //初始化全0
37 s[0]=1; //默认正数
38 len=2; //变量初始化为0
39 }
40 BigNum Nizhi() //排除符号位颠倒数组
41 {
42 BigNum ans;
43 ans.s[0]=s[0];
44 for(int i=1;i<=len/2;i++)
45 {
46 ans.s[i]=s[len-i];
47 ans.s[len-i]=s[i];
48 }
49 ans.len=len;
50 return ans;
51 }
52 friend bool operator<(const BigNum &a,const BigNum &b);
53 friend bool operator>(const BigNum &a,const BigNum &b);
54 friend bool operator<=(const BigNum &a,const BigNum &b);
55 friend bool operator>=(const BigNum &a,const BigNum &b);
56 friend BigNum operator+(BigNum a,BigNum b);
57 friend void operator+=(BigNum &a,BigNum b);
58 friend BigNum operator-(BigNum a,BigNum b);
59 friend void operator-=(BigNum &a,BigNum b);
60 friend BigNum operator*(BigNum a,BigNum b);
61 friend void operator*=(BigNum &a,BigNum b);
62 friend BigNum operator/(BigNum a,BigNum b);
63 friend void operator/=(BigNum &a,BigNum b);
64 friend BigNum operator%(BigNum &a,BigNum b);
65 friend void operator%=(BigNum &a,BigNum b);
66 friend bool operator==(const BigNum &a,const BigNum &b);
67 void operator=(const int a);
68 void operator=(const char *a);
69 BigNum operator--();
70 BigNum operator--(int);
71 BigNum operator++();
72 BigNum operator++(int);
73 };
74 bool operator<(const BigNum &a,const BigNum &b)
75 {
76 bool flag;
77 if(a.s[0]==-1&&b.s[0]==1) return 1; //如果a为负,b为正,那么a<b
78 else if(a.s[0]==1&&b.s[0]==-1) return 0; //如果a为正,b为负,那么a>b
79 else if(a.s[0]==1&&b.s[0]==1) flag=1; //如果a、b都为正,flag=1,表示a、b大小和符号无关
80 else flag=0; //如果a、b都为负,flag=0,表示a、b大小和符号有关
81 // flag=1 时,a、b大小和除符号外的数字大小成正比,反之反比
82 if(a.len>b.len) return !flag; //a的位数多,所以a大,返回0
83 else if(a.len<b.len) return flag; //a的位数少,所以a小,返回1
84 else
85 {
86 int i=a.len; //从最高位开始比
87 while(i-->1)
88 {
89 if(a.s[i]>b.s[i]) return !flag;
90 else if(a.s[i]<b.s[i]) return flag;
91 }
92 return 0; //没有差异即相等返回0
93 }
94 }
95 bool operator<=(const BigNum &a,const BigNum &b) //同 <
96 {
97 bool flag; // flag=1 表示两者都是正的 =0表示两者都是负的
98 if(a.s[0]==-1&&b.s[0]==1) return 1;
99 else if(a.s[0]==1&&b.s[0]==-1) return 0;
100 else if(a.s[0]==1&&b.s[0]==1) flag=1;
101 else flag=0;
102 // flag 表示1 ,!flag 表示0
103 if(a.len>b.len) return !flag;
104 else if(a.len<b.len) return flag;
105 else
106 {
107 int i=a.len;
108 while(i-->1)
109 {
110 if(a.s[i]>b.s[i]) return !flag;
111 else if(a.s[i]<b.s[i]) return flag;
112 }
113 return 1;
114 }
115 }
116 bool operator>(const BigNum &a,const BigNum &b)
117 {
118 return !(a<=b);
119 }
120 bool operator>=(const BigNum &a,const BigNum &b)
121 {
122 return !(a<b);
123 }
124 bool operator==(const BigNum &a,const BigNum &b)
125 {
126 if(a.s[0]==-1&&b.s[0]==1) return 0;
127 else if(a.s[0]==1&&b.s[0]==-1) return 0;
128 if(a.len>b.len) return 0;
129 else if(a.len<b.len) return 0;
130 else
131 {
132 int i=a.len;
133 while(i-->1)
134 {
135 if(a.s[i]>b.s[i]) return 0;
136 else if(a.s[i]<b.s[i]) return 0;
137 }
138 return 1;
139 }
140 }
141 BigNum operator-(BigNum a,BigNum b)
142 {
143 BigNum ans;
144 if(a.s[0]==1&&b.s[0]==-1) //如果a正,b负,那么等同于a+|b|
145 {
146 b.s[0]=1;
147 return a+b;
148 }
149 else if(a.s[0]==-1&&b.s[0]==1) //如果a负,b正,那么等同于-(|a|+b)
150 {
151 a.s[0]=1;
152 ans=a+b;
153 ans.s[0]=-1;
154 return ans;
155 }
156 else if(a.s[0]==-1&&b.s[0]==-1) //如果a负,b负,那么等同于|b|-|a|
157 {
158 a.s[0]=1;
159 b.s[0]=1;
160 return b-a;
161 }
162 else //进到这一区域的,a为正,b为正
163 {
164 if(a<b) //如果a<b,那么等同于-(b-a)
165 {
166 ans=b-a;
167 ans.s[0]=-1;
168 }
169 else //进到这一区域a、b为正,且a>b,也就是说减出来的绝对是正数
170 {
171 int i=0;
172 int lm=a.len>b.len?a.len:b.len; //由于减出来必定是正数,不需要考虑lm-1位<0的情况
173 for(int i=1;i<lm;i++)
174 {
175 int tmp=ans.s[i]+a.s[i]-b.s[i];
176 if(tmp<0)
177 {
178 ans.s[i+1]--;
179 tmp+=10;
180 }
181 ans.s[i]=tmp;
182 }
183 while(lm>2) //清楚高位0,最多清楚到0为止
184 {
185 if(ans.s[lm-1]==0) lm--;
186 else break;
187 }
188 ans.len=lm;
189 }
190 }
191 return ans;
192 }
193 void operator-=(BigNum &a,BigNum b)
194 {
195 a=a-b;
196 }
197 BigNum operator+(BigNum a,BigNum b)
198 {
199 BigNum ans;
200 int lm=a.len>b.len?a.len:b.len;
201 if(a.s[0]*b.s[0]==1) //如果两者符号位相同
202 {
203 ans.s[0]=a.s[0]; //结果符号位与任意一个相同
204 for(int i=1;i<lm;i++)
205 {
206 int tmp=ans.s[i]+a.s[i]+b.s[i];
207 if(tmp>=10)
208 {
209 ans.s[i+1]++;
210 }
211 ans.s[i]=tmp%10;
212 }
213 if(ans.s[lm]==0) ans.len=lm; //如果最高位没有进位,那么长度不变,否则加1
214 else ans.len=lm+1;
215 }
216 else //如果a、b符号不同,可以转化为减法
217 {
218 if(a.s[0]==1)
219 {
220 b.s[0]=1;
221 return a-b;
222 }
223 else
224 {
225 a.s[0]=1;
226 return b-a;
227 }
228 }
229 return ans;
230 }
231 void operator+=(BigNum &a,BigNum b)
232 {
233 a=a+b;
234 }
235
236 BigNum operator*(BigNum a,BigNum b)
237 {
238 BigNum ans;
239 ans.s[0]=a.s[0]*b.s[0]; //乘法和除法的符号位简单处理
240 for(int i=1;i<a.len;i++)
241 {
242 for(int j=1;j<b.len;j++)
243 {
244 ans.s[i+j-1]+=a.s[i]*b.s[j]; //先存
245 }
246 }
247 int maxt=a.len+b.len; //最多位数
248 for(int i=1;i<maxt;i++) //处理每个位上的数
249 {
250 if(ans.s[i]>=10)
251 {
252 ans.s[i+1]+=ans.s[i]/10;
253 ans.s[i]=ans.s[i]%10;
254 }
255 }
256 int i;
257 for(i=maxt;i>1;i--) //处理高位0
258 {
259 if(ans.s[i]!=0) break;
260 }
261 ans.len=i+1;
262 return ans;
263 }
264 void operator*=(BigNum &a,BigNum b)
265 {
266 a=a*b;
267 }
268 BigNum operator/(BigNum a,BigNum b)
269 {
270 /*
271 思路: 首先从a的高位往低位数,如果还<b,那么就再加1位,知道>=b,然后遍历1-9,判断此时
272 合适取值,和平常手动计算思路一样
273 */
274 BigNum ans;
275 ans.s[0]=a.s[0]*b.s[0];
276 b.s[0]=1; //中途比较需要
277 BigNum tmp; //添位取值
278 tmp.len=1; //刚开始为无值,就是说连a的最高位都还没纳入
279 BigNum zj; //中间变量,比较时需要,由于数组是倒置的,所以加这一变量
280 ans.len=1; //答案还是空的
281 int j=a.len; //j固定指向a,不断取值
282 bool match=1; //match为0退出循环
283 while(1)
284 {
285 while(1) //如果还没取够值,就继续加位
286 {
287 if(j==1) //如果a到了符号位,那么可以退出循环了
288 {
289 match=0;
290 break;
291 }
292 tmp.s[tmp.len++]=a.s[--j]; //加位,由于开始不好确定位数,所以直接正向不好办
293 zj=tmp.Nizhi(); //数组颠倒后再去比较
294 if(b<=zj) break; //如果b<=zj了,就可以退出了,否则该位为0
295 ans.s[ans.len++]=0;
296 }
297 if(!match) break; //match为0退出循环
298 int i;
299 BigNum r=b; //r为最大容许的乘后值
300 for(i=2;i<=10;i++)
301 {
302 BigNum p;
303 p.s[p.len-1]=i; //获得 2 - 10 . 赋值过程不符常规,但由于下一步是乘,可以忽略该bug
304 BigNum u=b*p; //如果u超过了中间变量,可以退出了,同i应该减1
305 if(zj<u) break;
306 r=u; //乘得的最大数
307 }
308 i--;
309 ans.s[ans.len++]=i; //逐位求值
310 zj=zj-r; //获得余数
311 BigNum q;
312 if(zj==q) zj.len--; //如果余数为0,那么去掉,不能出现00,不然会出错
313 tmp=zj.Nizhi(); //重新逆置
314 }
315 ans=ans.Nizhi(); //逆置获得答案
316 while(ans.s[ans.len-1]==0&&ans.len>2) //高位消0
317 {
318 ans.len--;
319 }
320 return ans;
321 }
322 void operator/=(BigNum &a,BigNum b)
323 {
324 a=a/b;
325 }
326 BigNum operator%(BigNum &a,BigNum b)
327 {
328 b.s[0]=1;
329 BigNum tmp;
330 tmp.len=1;
331 BigNum zj;
332 int j=a.len;
333 bool match=1;
334 while(1)
335 {
336 while(1)
337 {
338 if(j==1)
339 {
340 match=0;
341 break;
342 }
343 tmp.s[tmp.len++]=a.s[--j];
344 zj=tmp.Nizhi();
345 if(b<=zj) break;
346 }
347 if(!match) break;
348 int i;
349 BigNum r=b;
350 for(i=2;i<=10;i++)
351 {
352 BigNum p;
353 p.s[p.len-1]=i;
354 BigNum u=b*p;
355 if(zj<u) break;
356 r=u;
357 }
358 i--;
359 zj=zj-r;
360 BigNum q;
361 if(zj==q) zj.len--;
362 tmp=zj.Nizhi();
363 }
364 if(zj.len==1)
365 {
366 zj.Clear();
367 }
368 return zj;
369 }
370 void operator%=(BigNum &a,BigNum b)
371 {
372 a=a%b;
373 }
374 void BigNum::operator=(int a)
375 {
376 Clear();
377 if(a<0)
378 {
379 s[0]=-1;
380 a=-a;
381 }
382 len=1;
383 while(a)
384 {
385 s[len++]=a%10;
386 a/=10;
387 }
388 }
389 void BigNum::operator=(const char *a)
390 {
391 Clear();
392 if(*a=='-')
393 {
394 s[0]=-1;
395 a++;
396 }
397 len=1;
398 while(*a&&*a=='0') a++;
399 while(*a)
400 {
401 s[len++]=*a-'0';
402 a++;
403 }
404 if(len==1) len=2;
405 *this=Nizhi();
406 }
407 BigNum BigNum::operator--() // --a;
408 {
409 BigNum tmp;
410 tmp=-1;
411 *this+=tmp;
412 return *this;
413 }
414 BigNum BigNum::operator--(int) // a--;
415 {
416 BigNum ans;
417 ans=*this;
418 BigNum tmp;
419 tmp=-1;
420 *this+=tmp;
421 return ans;
422 }
423 BigNum BigNum::operator++() // ++a;
424 {
425 BigNum tmp;
426 tmp=1;
427 *this+=tmp;
428 return *this;
429 }
430 BigNum BigNum::operator++(int) // a++;
431 {
432 BigNum ans;
433 ans=*this;
434 BigNum tmp;
435 tmp=1;
436 *this+=tmp;
437 return ans;
438 }
439 int main()
440 {
441
442 return 0;
443 }