北大的ACM 1001
代码纯手动编写 - -
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 5 6 class BigNumber 7 { 8 struct BigNumberNode 9 { 10 BigNumberNode():n(0), prev(NULL), next(NULL){} 11 BigNumberNode(int N):n(N), prev(NULL), next(NULL){} 12 13 int n; 14 BigNumberNode *prev, *next; 15 }; 16 17 BigNumberNode *head, *tail; 18 int dot_before; // 小数点之前的数量 19 int dot_later; // 小数点之后的数量 20 21 void InsertNodeAtBegin(int n) 22 { 23 BigNumberNode *new_node = new BigNumberNode(n); 24 if(head != NULL) 25 { 26 head->prev = new_node; 27 new_node->prev = NULL; 28 new_node->next = head; 29 head = new_node; 30 } 31 else 32 { 33 head = new_node; 34 tail = new_node; 35 new_node->prev = NULL; 36 new_node->next = NULL; 37 } 38 } 39 40 void InsetNodeAtEnd(int n) 41 { 42 BigNumberNode *new_node = new BigNumberNode(n); 43 if(head != NULL) 44 { 45 new_node->prev = tail; 46 new_node->next = NULL; 47 tail->next = new_node; 48 tail = new_node; 49 } 50 else 51 { 52 head = new_node; 53 tail = new_node; 54 new_node->prev = NULL; 55 new_node->next = NULL; 56 } 57 } 58 59 void DeleteBegin() 60 { 61 if(head != NULL) 62 { 63 if (head->next != NULL) 64 { 65 BigNumberNode* temp = head->next; 66 delete head; 67 head = temp; 68 temp->prev = NULL; 69 70 if (dot_before != 0) 71 { 72 dot_before--; 73 } 74 else 75 { 76 dot_later--; 77 } 78 } 79 else 80 { 81 Free(); 82 } 83 } 84 } 85 86 void DeleteEnd() 87 { 88 if(tail != NULL) 89 { 90 if (tail->prev != NULL) 91 { 92 BigNumberNode* temp = tail->prev; 93 delete tail; 94 tail = temp; 95 temp->next = NULL; 96 97 if (dot_later != 0) 98 { 99 dot_later--; 100 } 101 else 102 { 103 dot_before--; 104 } 105 } 106 else 107 { 108 Free(); 109 } 110 } 111 } 112 113 // 去除前/后导 0 114 // 去除前/后导 0 115 void ClearZeros() 116 { 117 // 后导 0 118 BigNumberNode *p; 119 120 int max_limit = dot_later; 121 for(int i = 0; i < max_limit; i++) 122 { 123 p = tail; 124 125 if(p->n == 0) 126 { 127 DeleteEnd(); 128 } 129 else 130 { 131 break; 132 } 133 } 134 135 // 前导 0 136 max_limit = dot_before; 137 for(int i = 0; i < max_limit; i++) 138 { 139 p = head; 140 141 if(p->n == 0) 142 { 143 DeleteBegin(); 144 } 145 else 146 { 147 break; 148 } 149 } 150 } 151 152 BigNumber Mul(const BigNumber &Scale) 153 { 154 const BigNumber &a = *this, &b = Scale; 155 BigNumber sum_big_number; 156 157 int sum = 0; 158 int reserve = 0; 159 int tag = 0; 160 161 BigNumberNode *pa = a.tail, *pb = b.tail; 162 163 // xxxxxx a 164 // xxx b 165 // --------- Mul 166 // xxxxxx 167 // xxxxxx 168 // xxxxxx 169 // --------- Add 170 // xxxxxxxxx 171 172 while(pb) 173 { 174 BigNumber temp_big_number; 175 pa = a.tail; 176 while(pa) 177 { 178 sum = pa->n * pb->n + reserve; 179 reserve = sum / 10; 180 temp_big_number.InsertNodeAtBegin(sum - reserve * 10); 181 temp_big_number.dot_before++; 182 pa = pa->prev; 183 } 184 185 if (reserve) 186 { 187 temp_big_number.InsertNodeAtBegin(reserve); 188 temp_big_number.dot_before++; 189 reserve = 0; 190 } 191 192 for (int i = 0; i < tag; i++) 193 { 194 temp_big_number.InsetNodeAtEnd(0); 195 temp_big_number.dot_before++; 196 } 197 198 sum_big_number += temp_big_number; 199 200 tag++; 201 pb = pb->prev; 202 } 203 204 sum_big_number.dot_later = a.dot_later + b.dot_later; 205 206 if (sum_big_number.dot_before > sum_big_number.dot_later) 207 { 208 sum_big_number.dot_before -= sum_big_number.dot_later; 209 } 210 else 211 { 212 int temp = sum_big_number.dot_later - sum_big_number.dot_before; 213 sum_big_number.dot_before = 0; 214 for (int i = 0; i < temp; i++) 215 { 216 sum_big_number.InsertNodeAtBegin(0); 217 } 218 } 219 220 sum_big_number.ClearZeros(); 221 222 return sum_big_number; 223 } 224 225 public: 226 227 ~BigNumber() 228 { 229 Free(); 230 } 231 232 BigNumber(): head(NULL), tail(NULL), dot_before(0), dot_later(0) 233 { 234 } 235 236 BigNumber(const char *Str): head(NULL), tail(NULL), dot_before(0), dot_later(0) 237 { 238 Free(); 239 AdaptFormString(Str); 240 } 241 242 BigNumber(const BigNumber& Source): head(NULL), tail(NULL), dot_before(0), dot_later(0) 243 { 244 *this = Source; 245 } 246 247 const BigNumber& operator=(const BigNumber& Source) 248 { 249 if (this != &Source) 250 { 251 this->Free(); 252 253 BigNumberNode *p = Source.head; 254 while(p) 255 { 256 this->InsetNodeAtEnd(p->n); 257 p = p->next; 258 } 259 260 this->dot_before = Source.dot_before; 261 this->dot_later = Source.dot_later; 262 } 263 264 return *this; 265 } 266 267 BigNumber operator+(const BigNumber Addend) 268 { 269 const BigNumber &a = *this, &b = Addend; 270 BigNumber new_number; 271 272 BigNumberNode *pa, *pb; 273 int sum, remain, odd; 274 int reserve = 0; 275 bool is_dot_before_longer_is_a; // 帮助标记小数点之前的部分 276 bool is_dot_later_longer_is_a; 277 278 // 小数点之后 279 if(a.dot_later > b.dot_later) 280 { 281 pa = a.tail; 282 pb = b.tail; 283 remain = b.dot_later; 284 odd = a.dot_later - b.dot_later; 285 is_dot_later_longer_is_a = true; 286 } 287 else 288 { 289 pa = b.tail; 290 pb = a.tail; 291 remain = a.dot_later; 292 odd = b.dot_later - a.dot_later; 293 is_dot_later_longer_is_a = false; 294 } 295 296 for (int i = 0; i < odd; i++) 297 { 298 new_number.InsertNodeAtBegin(pa->n); 299 new_number.dot_later++; 300 pa = pa->prev; 301 } 302 303 for (int i = 0; i < remain; i++) 304 { 305 sum = pa->n + pb->n + reserve; 306 reserve = sum / 10; 307 new_number.InsertNodeAtBegin(sum - reserve * 10); 308 new_number.dot_later++; 309 pa = pa->prev; 310 pb = pb->prev; 311 } 312 313 // 小数点之前 314 if(a.dot_before > b.dot_before) 315 { 316 remain = b.dot_before; 317 odd = a.dot_before - b.dot_before; 318 is_dot_before_longer_is_a = true; 319 } 320 else 321 { 322 remain = a.dot_before; 323 odd = b.dot_before - a.dot_before; 324 is_dot_before_longer_is_a = false; 325 } 326 327 BigNumberNode *temp; // 用于交换 pa pb 328 if (is_dot_before_longer_is_a && is_dot_later_longer_is_a 329 || !is_dot_before_longer_is_a && !is_dot_later_longer_is_a) 330 { 331 // 不用交换 332 } 333 else 334 { 335 temp = pa; 336 pa = pb; 337 pb = temp; 338 } 339 340 341 for (int i = 0; i < remain; i++) 342 { 343 sum = pa->n + pb->n + reserve; 344 reserve = sum / 10; 345 new_number.InsertNodeAtBegin(sum - reserve * 10); 346 new_number.dot_before++; 347 pa = pa->prev; 348 pb = pb->prev; 349 } 350 351 for (int i = 0; i < odd; i++) 352 { 353 sum = pa->n + reserve; 354 reserve = sum / 10; 355 new_number.InsertNodeAtBegin(sum - reserve * 10); 356 new_number.dot_before++; 357 pa = pa->prev; 358 } 359 360 // 检测是否最后还有一位 361 if (reserve) 362 { 363 new_number.InsertNodeAtBegin(reserve); 364 new_number.dot_before++; 365 reserve = 0; 366 } 367 368 new_number.ClearZeros(); 369 370 return new_number; 371 } 372 373 BigNumber operator*(const BigNumber& Scale) 374 { 375 return Mul(Scale); 376 } 377 378 BigNumber& operator+=(const BigNumber Addend) 379 { 380 BigNumber &a = *this; 381 const BigNumber &b = Addend; 382 383 BigNumberNode *pa = a.tail, *pb = b.tail; 384 int sum = 0, remain = 0, odd = 0; 385 int reserve = 0; 386 387 // 小数点之后 388 if(a.dot_later > b.dot_later) 389 { 390 remain = b.dot_later; 391 odd = a.dot_later - b.dot_later; 392 393 for (int i = 0; i < odd; i++) 394 { 395 pa = pa->prev; 396 } 397 } 398 else 399 { 400 remain = a.dot_later; 401 odd = b.dot_later - a.dot_later; 402 403 char *odd_n = new char[odd]; 404 for (int i = 1; i <= odd; i++) 405 { 406 odd_n[odd - i] = pb->n; 407 pb = pb->prev; 408 } 409 410 for (int i = 0; i < odd; i++) 411 { 412 a.InsetNodeAtEnd(odd_n[i]); 413 a.dot_later++; 414 } 415 delete odd_n; 416 } 417 418 for (int i = 0; i < remain; i++) 419 { 420 sum = pa->n + pb->n + reserve; 421 reserve = sum / 10; 422 pa->n = sum - reserve * 10; 423 424 pa = pa->prev; 425 pb = pb->prev; 426 } 427 428 // 小数点之前 429 if(a.dot_before > b.dot_before) 430 { 431 remain = b.dot_before; 432 odd = a.dot_before - b.dot_before; 433 434 for (int i = 0; i < remain; i++) 435 { 436 sum = pa->n + pb->n + reserve; 437 reserve = sum / 10; 438 pa->n = sum - reserve * 10; 439 440 pa = pa->prev; 441 pb = pb->prev; 442 } 443 444 for (int i = 0; i < odd; i++) 445 { 446 sum = pa->n + reserve; 447 reserve = sum / 10; 448 pa->n = sum - reserve * 10; 449 450 pa = pa->prev; 451 } 452 } 453 else 454 { 455 remain = a.dot_before; 456 odd = b.dot_before - a.dot_before; 457 458 for (int i = 0; i < remain; i++) 459 { 460 sum = pa->n + pb->n + reserve; 461 reserve = sum / 10; 462 pa->n = sum - reserve * 10; 463 464 pa = pa->prev; 465 pb = pb->prev; 466 } 467 468 for (int i = 0; i < odd; i++) 469 { 470 sum = pb->n + reserve; 471 reserve = sum / 10; 472 a.InsertNodeAtBegin(sum - reserve * 10); 473 a.dot_before++; 474 pb = pb->prev; 475 } 476 477 } 478 479 // 检测是否最后还有一位 480 if (reserve) 481 { 482 a.InsertNodeAtBegin(reserve); 483 a.dot_before++; 484 } 485 486 a.ClearZeros(); 487 488 return *this; 489 } 490 491 void _Print() 492 { 493 if(dot_before == 0 && dot_later == 0) 494 { 495 putchar('0'); 496 } 497 else if (dot_later == 0) 498 { 499 BigNumberNode *p = head; 500 501 while(p) 502 { 503 putchar(p->n + '0'); 504 p = p->next; 505 } 506 } 507 else 508 { 509 BigNumberNode *p = head; 510 511 for(int i = 0; i < dot_before; i++) 512 { 513 putchar(p->n + '0'); 514 p = p->next; 515 } 516 517 putchar('.'); 518 519 while(p) 520 { 521 putchar(p->n + '0'); 522 p = p->next; 523 } 524 } 525 } 526 527 void PrintString() 528 { 529 if(dot_before == 0 && dot_later == 0) 530 { 531 putchar('0'); 532 } 533 else if (dot_later == 0) 534 { 535 char *temp = new char[dot_before + dot_later + 2], *ptemp = temp; 536 BigNumberNode *p = head; 537 538 while(p) 539 { 540 *ptemp = p->n + '0'; 541 ptemp++; 542 p = p->next; 543 } 544 *ptemp = 0; 545 546 std::cout<<temp<<'\n'; 547 delete[] temp; 548 } 549 else 550 { 551 char *temp = new char[dot_before + dot_later + 2], *ptemp = temp; 552 BigNumberNode *p = head; 553 554 for(int i = 0; i < dot_before; i++) 555 { 556 *ptemp = p->n + '0'; 557 ptemp++; 558 p = p->next; 559 } 560 561 *ptemp = '.'; 562 ptemp++; 563 564 while(p) 565 { 566 *ptemp = p->n + '0'; 567 ptemp++; 568 p = p->next; 569 } 570 *ptemp = 0; 571 572 std::cout<<temp<<'\n'; 573 delete[] temp; 574 } 575 } 576 577 void Free() 578 { 579 BigNumberNode *p = head, *temp; 580 581 while(p) 582 { 583 temp = p; 584 p = p->next; 585 delete temp; 586 } 587 588 head = NULL; 589 tail = NULL; 590 dot_before = 0; 591 dot_later = 0; 592 } 593 594 // 从字符串建立数据,未加入错误检测 595 void AdaptFormString(const char *Str) 596 { 597 Free(); 598 599 const char *pc = Str; 600 601 // 小数点之前 602 while(*pc) 603 { 604 if(*pc != '.') // 0 ~ 9 605 { 606 InsetNodeAtEnd(*pc - '0'); 607 dot_before++; 608 pc++; 609 } 610 else // 小数点之后 611 { 612 pc++; 613 while(*pc) 614 { 615 InsetNodeAtEnd(*pc - '0'); 616 dot_later++; 617 pc++; 618 } 619 break; 620 } 621 } 622 623 ClearZeros(); 624 } 625 626 }; 627 628 // 自顶向下的动态规划 629 BigNumber* BigNumberPowUP(BigNumber* result[], int pow) 630 { 631 if( result[pow] ) 632 { 633 return result[pow]; 634 } 635 else 636 { 637 int left = pow / 2; 638 int right = pow - left; 639 640 result[left] = BigNumberPowUP(result, left); 641 result[right] = BigNumberPowUP(result, right); 642 643 result[pow] = new BigNumber((*result[left]) * (*result[right])); 644 645 return result[pow]; 646 } 647 } 648 649 BigNumber BigNumberPow(const BigNumber& R, int pow) 650 { 651 BigNumber *result[26] = {0}; 652 653 result[1] = new BigNumber(R); 654 655 BigNumberPowUP(result, pow); 656 657 BigNumber Result = *result[pow]; 658 659 for (int i = 0; i <= pow; i++) 660 { 661 delete result[i]; 662 } 663 664 return Result; 665 } 666 667 int main(void) 668 { 669 char Rstr[10]; 670 int n; 671 672 while(scanf("%s%d", Rstr, &n) != EOF) 673 { 674 BigNumber result = BigNumberPow(Rstr, n); 675 result.PrintString(); 676 } 677 678 return 0; 679 }