Luogu2586 [ZJOI2008]杀蚂蚁 ---- 模拟
Luogu2586 [ZJOI2008]杀蚂蚁
题意
还是一道大模拟
https://www.luogu.org/problemnew/show/P2586
大概就是炮塔大蚂蚁的故事
下载这个游戏http://www.antbuster.net/Antbuster_12k_20090824.swf
还是比较难玩的
题解
就是预处理塔能打到的位置,然后直接把一局游戏分成几个阶段,同时每个阶段做了什么事也比较清楚,然后思路就比较清晰
一些经验:
- 尽量预处理一些静态的东西,然后不要临时算,这样会把整个函数弄得比较杂乱
- 容器什么的其实在Linux内是可以直接查看的,但是依然推荐通过运行输出查看,因为这样有一个跟踪容器变化的效果
- 每次更改代码之后记录一下改了什么地方,或者是版本控制
- 逻辑错误GDB不可行
- 然后这次精简了一些函数,可能对于整体效果来说还是比较可以的
1 //Created By Creeper_LKF 2 //Caution::We used "pragma" in the code 3 #include <cstdio> 4 #include <cctype> 5 #include <cassert> 6 #include <cstdlib> 7 #include <cstring> 8 #include <iostream> 9 10 #ifdef __gnu_linux__ 11 12 #include <fcntl.h> 13 #include <unistd.h> 14 #include <sys/mman.h> 15 16 #endif 17 18 #if __cplusplus < 201103L 19 20 #include <stdarg.h> 21 22 #endif 23 24 //Algorithm Heads 25 26 #include <list> 27 #include <cmath> 28 #include <queue> 29 #include <utility> 30 #include <algorithm> 31 32 33 using namespace std; 34 35 //FILE_NAME DEFINATION 36 37 //Debug Port 38 39 #define DEBUG_PORT 40 #define DEBUG 1 41 42 #ifdef ONLINE_JUDGE 43 #undef DEBUG_PORT 44 #endif 45 46 #ifdef DEBUG_PORT 47 #if __cplusplus < 201103L 48 # pragma message "Warning : C++11 Not Use" 49 #ifdef DEBUG 50 template<typename T> 51 extern inline void Debug(T tar){ 52 cerr << tar << endl; 53 } 54 template<typename Head, typename T, typename... Tail> 55 extern inline void Debug(Head head, T mid, Tail... tail){ 56 cerr << head << ' '; 57 Debug(mid, tail...); 58 } 59 #else 60 template<typename Head, typename T, typename... Tail> 61 extern inline void Debug(Head head, T mid, Tail... tail){ 62 return ; 63 } 64 #endif 65 #else 66 #ifdef DEBUG 67 template <typename T> 68 extern inline void Debug(T tar){ 69 cerr << tar << endl; 70 } 71 #else 72 template <typename T> 73 extern inline void Debug(T tar){ 74 return ; 75 } 76 #endif 77 #endif 78 #else 79 template <typename T> 80 extern inline void Debug(T tar){ 81 return ; 82 } 83 #endif 84 85 const char file_name[] = "b"; 86 87 #define NAME_SPACE 88 #define USING 89 90 #ifdef NAME_SPACE 91 namespace LKF{ 92 #endif 93 #define SF_READ 94 #define EOF_READ 95 // #define ONLINE_JUDGE 96 #define WRITE_ENDL 97 // #define FAST_WRITE 98 #define SPLIT_WRITE 99 const size_t MAX_BUF_SIZE = 50000000; 100 101 #define NEED_FILE 102 103 #ifdef FAST_WRITE 104 char outp[MAX_BUF_SIZE], *op = outp; 105 #endif 106 107 #ifdef ONLINE_JUDGE 108 #undef NEED_FILE 109 #endif 110 111 #ifdef FAST_WRITE 112 #ifndef WRITE_ENDL 113 #define WRITE_ENDL 114 #endif 115 #endif 116 117 extern inline void FILE_OPT(){ 118 #ifdef NEED_FILE 119 #define FILE_NAME file_name 120 char IN_FILE[sizeof(FILE_NAME) + 5], OUT_FILE[sizeof(FILE_NAME) + 5]; 121 strcpy(IN_FILE, FILE_NAME), strcpy(OUT_FILE, FILE_NAME); 122 strcat(IN_FILE, ".in"), strcat(OUT_FILE, ".out"); 123 freopen(IN_FILE, "r", stdin); 124 freopen(OUT_FILE, "w", stdout); 125 #endif 126 } 127 128 #ifdef __gnu_linux__ 129 130 char *pc; 131 132 extern inline void Main_Init(){ 133 static bool INITED = false; 134 if(INITED){ 135 #ifdef FAST_WRITE 136 fwrite(outp, 1, op - outp - 1, stdout); 137 #endif 138 fclose(stdin), fclose(stdout); 139 } else { 140 FILE_OPT(); 141 pc = (char *) mmap(NULL, lseek(0, 0, SEEK_END), PROT_READ, MAP_PRIVATE, 0, 0); 142 INITED = true; 143 } 144 } 145 146 #else 147 148 char buf[MAX_BUF_SIZE], *pc = buf; 149 150 extern inline void Main_Init(){ 151 static bool INITED = false; 152 if(INITED){ 153 #ifdef FAST_WRITE 154 fwrite(outp, 1, op - outp - 1, stdout); 155 #endif 156 fclose(stdin), fclose(stdout); 157 } else { 158 FILE_OPT(); 159 fread(buf, 1, MAX_BUF_SIZE, stdin); 160 INITED = true; 161 } 162 } 163 164 #endif 165 166 inline char read_ch(){ 167 char c; 168 while(isspace(c = *pc ++)); 169 return c; 170 } 171 172 #ifdef EOF_READ 173 174 #ifdef SF_READ 175 176 template<typename T> 177 static inline void read(T &num){ 178 num = 0; 179 char c, sf = 1; 180 while(isspace(c = *pc++)); 181 if(c == 45) sf = -1, c = *pc ++; 182 while(num = num * 10 + c - 48, isdigit(c = *pc++)); 183 num *= sf; 184 } 185 186 static inline int read(){ 187 int num = 0; 188 char c, sf = 1; 189 while(isspace(c = *pc++)); 190 if(c == 45) sf = -1, c = *pc ++; 191 while(num = num * 10 + c - 48, isdigit(c = *pc++)); 192 return num * sf; 193 } 194 195 static inline double read_dec(){ 196 double num = 0, decs = 1; 197 char c, sf = 1; 198 while(isspace(c = *pc ++)); 199 if(c == '-') sf = -1, c = *pc ++; 200 while(num = num * 10 + c - 48, isdigit(c = *pc ++)); 201 if(c != '.') return num * sf; 202 c = *pc ++; 203 while(num += (decs *= 0.1) * (c - 48), isdigit(c = *pc ++)); 204 return num * sf; 205 } 206 207 #else 208 209 template<typename T> 210 static inline T read(T &num){ 211 num = 0; 212 char c; 213 while (isspace(c = *pc++)); 214 while (num = num * 10 + c - 48, isdigit(c = *pc++)); 215 return num; 216 } 217 218 static inline int read(){ 219 int num = 0; 220 char c; 221 while (isspace(c = *pc++)); 222 while (num = num * 10 + c - 48, isdigit(c = *pc++)); 223 return num; 224 } 225 226 static inline double read_dec(){ 227 double num = 0, decs = 1; 228 char c; 229 while(isspace(c = *pc ++)); 230 while(num = num * 10 + c - 48, isdigit(c = *pc ++)); 231 if(c != '.') return num; 232 c = *pc ++; 233 while(num += (c - 48) * (decs *= 0.1), isdigit(c = *pc ++)); 234 return num; 235 } 236 237 #endif 238 239 #else 240 241 #ifdef SF_READ 242 243 template<typename T> 244 static inline void read(T &num){ 245 num = 0; 246 char c, sf = 1; 247 while((c = *pc++) < 45); 248 if(c == 45) sf = -1, c = *pc ++; 249 while(num = num * 10 + c - 48, (c = *pc++) >= 48); 250 num *= sf; 251 } 252 253 static inline int read(){ 254 int num = 0; 255 char c, sf = 1; 256 while((c = *pc++) < 45); 257 if(c == 45) sf = -1, c = *pc ++; 258 while(num = num * 10 + c - 48, (c = *pc++) >= 48); 259 return num * sf; 260 } 261 262 static inline double read_dec(){ 263 double num = 0, decs = 1; 264 char c, sf = 1; 265 while(isspace(c = *pc ++)); 266 if(c == '-') sf = -1, c = *pc ++; 267 while(num = num * 10 + c - 48, isdigit(c = *pc ++)); 268 if(c != '.') return num * sf; 269 c = *pc ++; 270 while(num += (decs *= 0.1) * (c - 48), isdigit(c = *pc ++)); 271 return num * sf; 272 } 273 274 #else 275 276 template<typename T> 277 static inline T read(T &num){ 278 num = 0; 279 char c; 280 while ((c = *pc++) < 48); 281 while (num = num * 10 + c - 48, (c = *pc++) >= 48); 282 return num; 283 } 284 285 static inline int read(){ 286 int num = 0; 287 char c; 288 while ((c = *pc++) < 48); 289 while (num = num * 10 + c - 48, (c = *pc++) >= 48); 290 return num; 291 } 292 293 static inline double read_dec(){ 294 double num = 0, decs = 1; 295 char c; 296 while(isspace(c = *pc ++)); 297 while(num = num * 10 + c - 48, isdigit(c = *pc ++)); 298 if(c != '.') return num; 299 c = *pc ++; 300 while(num += (c - 48) * (decs *= 0.1), isdigit(c = *pc ++)); 301 return num; 302 } 303 304 #endif 305 306 #endif 307 308 #ifdef FAST_WRITE 309 template <typename T> 310 inline void Call_Write(char Split, T tar){ 311 char buf[20]; 312 int top = 0; 313 if(tar == 0) *op ++ = 48; 314 else { 315 if(tar < 0) *op ++ = '-', tar = -tar; 316 while(tar) buf[++top] = tar % 10, tar /= 10; 317 while(top) *op ++ = buf[top --] ^ 48; 318 } 319 *op ++ = Split; 320 } 321 template <typename T> 322 inline void Call_Write(T tar){ 323 char buf[20]; 324 int top = 0; 325 if(tar == 0) *op ++ = 48; 326 else { 327 if(tar < 0) *op ++ = '-', tar = -tar; 328 while(tar) buf[++top] = tar % 10, tar /= 10; 329 while(top) *op ++ = buf[top --] ^ 48; 330 } 331 } 332 #endif 333 334 #ifdef FAST_WRITE 335 336 extern inline void write(){ 337 *op ++ = '\n'; 338 } 339 340 template<typename T> 341 extern inline void write(T tar){ 342 Call_Write(tar); 343 #ifdef WRITE_ENDL 344 write(); 345 #endif 346 } 347 348 #if __cplusplus >= 201103L 349 350 # pragma GCC diagnostic push 351 # pragma GCC diagnostic ignored "-Wunused-parameter" 352 353 template<typename T> 354 extern inline void write(char Split, T tar){ 355 Call_Write(tar); 356 #ifdef WRITE_ENDL 357 write(); 358 #endif 359 } 360 361 # pragma GCC diagnostic pop 362 # pragma message "Warning : pragma used" 363 364 template<typename Head, typename T, typename... Tail> 365 extern inline void write(char Split, Head head, T mid, Tail... tail){ 366 Call_Write(Split, head); 367 write(Split, mid, tail...); 368 } 369 370 #else 371 372 template <typename T> 373 extern inline void write(char Split, T tar){ 374 Call_Write(tar); 375 #ifdef WRITE_ENDL 376 write(); 377 #endif 378 } 379 380 #endif 381 382 #else 383 384 extern inline void write(){ 385 cout << endl; 386 } 387 388 template<typename T> 389 extern inline void write(T tar){ 390 cout << tar; 391 #ifdef WRITE_ENDL 392 write(); 393 #endif 394 } 395 396 #if __cplusplus >= 201103L 397 398 template<typename T> 399 extern inline void write(char Split, T tar){ 400 cout << tar << Split; 401 #ifdef WRITE_ENDL 402 write(); 403 #endif 404 } 405 406 template<typename Head, typename T, typename... Tail> 407 extern inline void write(char Split, Head head, T mid, Tail... tail){ 408 #ifdef SPLIT_WRITE 409 cout << head << Split; 410 #else 411 cout << head; 412 #endif 413 write(Split, mid, tail...); 414 } 415 416 #else 417 418 template <typename T> 419 extern inline void write(char Split, T tar){ 420 cout << tar << Split; 421 #ifdef WRITE_ENDL 422 write(); 423 #endif 424 } 425 426 #endif 427 428 #endif 429 430 template <typename T> 431 extern inline void upmax(T &x, const T &y){ 432 if(x < y) x = y; 433 } 434 template <typename T> 435 extern inline void upmin(T &x, const T &y){ 436 if(x > y) x = y; 437 } 438 439 #if __cplusplus >= 201103L 440 441 template<typename T> 442 extern inline T max(T tar){ 443 return tar; 444 } 445 446 template<typename T> 447 extern inline T min(T tar){ 448 return tar; 449 } 450 451 template <typename Head, typename T, typename... Tail> 452 extern inline Head max(Head head, T mid, Tail... tail){ 453 Head tmp = max(mid, tail...); 454 return head > tmp ? head : tmp; 455 } 456 template <typename Head, typename T, typename... Tail> 457 extern inline Head min(Head head, T mid, Tail... tail){ 458 Head tmp = min(mid, tail...); 459 return head < tmp ? head : tmp; 460 } 461 462 #else 463 464 template <typename T> 465 extern inline T max(T a, T b){ 466 return a > b ? a : b; 467 } 468 template <typename T> 469 extern inline T min(T a, T b){ 470 return a < b ? a : b; 471 } 472 473 #endif 474 475 template <typename T> 476 extern inline T abs(T tar){ 477 return tar < 0 ? -tar : tar; 478 } 479 template <typename T> 480 extern inline void swap(T &a, T &b){ 481 T t = a; 482 a = b; 483 b = t; 484 } 485 #ifdef NAME_SPACE 486 } 487 #endif 488 489 //Algorithm 490 491 #ifdef NAME_SPACE 492 namespace LKF{ 493 #endif 494 495 template <typename T> 496 struct Queue{ 497 size_t s, t; 498 T *q; 499 Queue(){ 500 s = 1, t = 0; 501 q = NULL; 502 } 503 Queue(size_t siz){ 504 s = 1, t = 0; 505 q = (T*)malloc(sizeof(T) * siz); 506 assert(q != NULL); 507 } 508 inline void Re_Init(size_t siz){ 509 q = (T*)realloc(q, sizeof(T) * siz); 510 assert(q != NULL); 511 } 512 ~Queue(){ 513 delete[] q; 514 } 515 inline void clear(){ 516 s = 1, t = 0; 517 } 518 inline bool empty(){ 519 return s > t; 520 } 521 inline size_t size(){ 522 return t - s + 1; 523 } 524 inline void push(T tar){ 525 q[++ t] = tar; 526 } 527 inline void pop_front(){ 528 s ++; 529 } 530 inline void pop_back(){ 531 t --; 532 } 533 inline T front(){ 534 return q[s]; 535 } 536 inline T back(){ 537 return q[t]; 538 } 539 }; 540 541 template <typename T> 542 struct Stack{ 543 size_t t; 544 T *s; 545 Stack(){ 546 t = 0; 547 s = NULL; 548 } 549 Stack(size_t siz){ 550 t = 0; 551 s = (T*)malloc(sizeof(T) * siz); 552 assert(s != NULL); 553 } 554 inline void Re_Init(size_t siz){ 555 s = (T*)realloc(s, sizeof(T) * siz); 556 assert(s != NULL); 557 } 558 ~Stack(){ 559 delete[] s; 560 } 561 inline void clear(){ 562 t = 0; 563 } 564 inline bool empty(){ 565 return t == 0; 566 } 567 inline size_t size(){ 568 return t; 569 } 570 inline void push(T tar){ 571 s[++ t] = tar; 572 } 573 inline T top(){ 574 return s[t]; 575 } 576 inline void pop(){ 577 t --; 578 } 579 }; 580 581 #ifdef NAME_SPACE 582 } 583 #endif 584 585 #ifdef USING 586 587 #ifdef NAME_SPACE 588 using LKF::pc; 589 using LKF::read_ch; 590 using LKF::read_dec; 591 using LKF::read; 592 using LKF::Main_Init; 593 using LKF::write; 594 using LKF::upmax; 595 using LKF::upmin; 596 using LKF::max; 597 using LKF::min; 598 using LKF::abs; 599 // using LKF::swap; 600 #else 601 using ::pc; 602 using ::read_ch; 603 using ::read_dec; 604 using ::read; 605 using ::Main_Init; 606 using ::write; 607 using ::upmax; 608 using ::upmin; 609 using ::max; 610 using ::min; 611 using ::abs; 612 // using ::swap; 613 #endif 614 615 #endif 616 617 //Source Code 618 619 620 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Debug_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 621 #if DEBUG 622 623 //Caution: Do Not Inline 624 //Do Not Open In Dev_CPP 625 //Please Compile it at LEAST in std=c++11 626 //This is the Release Version 627 628 void Print_Array(int s, int t, int *arr, string Name){ 629 cout << Name << " Begin" << endl; 630 for(int i = s; i < t; i++) cout << arr[i] << ' '; 631 cout << Name << " End" << endl; 632 } 633 634 template <typename T> 635 void Print_List(T B, T E, string Name){ 636 cout << Name << " Begin" << endl; 637 for(T it = B; it != E; it++) 638 cout << it -> x << ' '; 639 cout << endl << Name << " End" << endl; 640 } 641 642 643 #endif 644 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Read_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 645 646 /*char buf[1000001], *pc = buf; 647 648 extern inline void Main_Init(){ 649 #if DEBUG 650 // freopen("in.in", "r", stdin); 651 // freopen("TIT.out", "w", stdout); 652 #endif 653 fread(buf, 1, 1000000, stdin); 654 } 655 656 extern inline char get_char(){ 657 return *pc++; 658 } 659 660 extern inline void unget_char(){ 661 pc--; 662 } 663 664 inline int read(){ 665 int num = 0; 666 char c; 667 while((c = get_char()) < 48); 668 while(num = num * 10 + c - 48, (c = get_char()) >= 48); 669 return num; 670 }*/ 671 672 //Caution:: 673 //Do not omit parentheses 674 675 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Defination_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 676 677 /*#ifdef max 678 #undef max 679 #endif 680 681 #ifdef swap 682 #undef swap 683 #endif 684 685 #ifdef min 686 #undef min 687 #endif*/ 688 689 const int MAXN = 15, MAXS = 25, MAXT = 222222; 690 const int ING = 0, GO = 1;//游戏状态 691 const int Step_CXX[5][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}, {0, 0}};//注意:已排序 692 693 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Variable_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 694 695 int N, M, S, D, R, T, Time, tot, Ant, Game_State; 696 vector<int> In_Tower[MAXN][MAXN]; 697 bool Forbid[MAXN][MAXN], Ori[MAXN][MAXN]; 698 int Pher[MAXN][MAXN];//由于地图要进行数组操作,所以不存结构体 699 int Pow[233], X_IN[MAXN], Y_IN[MAXN]; 700 bool Is_Cake = true; 701 702 template <typename X, typename Y> 703 struct P{ 704 X x; 705 Y y; 706 P(){} 707 P(X _x, Y _y){x = _x, y = _y;} 708 }; 709 710 struct A{ 711 int Level, Birth, Health, Survival; 712 bool Cake, Death; 713 P<int, int> Pos, LPos; 714 inline bool operator < (const A &tar) const { 715 return Survival > tar.Survival; 716 } 717 }; 718 719 P<int, int> Towers[MAXS]; 720 721 struct T{ 722 int Target; 723 vector<P<int, double> > In_T; 724 }Tower[MAXS]; 725 726 list<A> Ants; 727 list<A>::iterator Pross[MAXN]; 728 729 inline bool cmp (const P<int, double> &a, const P<int, double> &b){//注意,这里的<为防御塔设计,x为蚂蚁编号,y为距离 730 return a.y == b.y ? Pross[a.x] -> Birth < Pross[b.x] -> Birth : a.y < b.y; 731 } 732 733 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Mini_Function__Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 734 735 /*template <typename T> 736 extern inline T min(T a, T b){ 737 return a < b ? a : b; 738 } 739 740 template <typename T> 741 extern inline T max(T a, T b){ 742 return a > b ? a : b; 743 } 744 745 template <typename T> 746 extern inline void swap(T &a, T &b){ 747 T t = a; 748 a = b; 749 b = t; 750 }*/ 751 752 template <typename T> 753 extern inline T pow_2(T tar){ 754 return tar * tar; 755 } 756 757 inline double Get_Dis(int x0, int y0, int x1, int y1){ 758 return sqrt(pow_2(x0 - x1) + pow_2(y1 - y0)); 759 } 760 761 inline bool Is_Cross(int x, int y, int x1, int y1, int r1){ 762 double dis = Get_Dis(x, y, x1, y1); 763 return dis <= double(r1); 764 } 765 766 inline bool Can_Be_Hit(int x0, int y0, int x2, int y2, int x1, int y1){//圆信息+蚂蚁信息+线段末端 767 if((x2 == x0 && y2 == y0) || (x2 == x1 && y2 == y1)) return true; 768 int l1 = min(x0, x1), r1 = max(x0, x1), l2 = min(y0, y1), r2 = max(y0, y1); 769 if(x2 < l1 || x2 > r1 || y2 < l2 || y2 > r2) return false; 770 // int s1 = x2 > x0 ? 1 : -1, s2 = y2 > y0 ? 1 : -1;//注意圆的半径是谁的 771 // if(!(s1 * x0 <= s1 * x1 && s1 * x1 <= s1 * x2) && (s2 * y0 <= s2 * y1 && s2 * y1 <= s2 * y2)) return false; 772 // if(x1 == x0) return double(abs(x1 - x2)) <= 0.5; 773 if(x1 == x0) return abs(x1 - x0) <= 0.5; 774 double r = 0.5, k = double(1.0 * (y1 - y0) / (x1 - x0)), b = double(1.0 * y0 - double(x0 * k)); 775 double p1 = pow_2(k * x2 - y2 + b); 776 double p2 = r * r * (k * k + 1); 777 return p1 <= p2; 778 // double p1 = pow_2(double(2 * k * b - 2 * x0 * x0 - 2 * y0 * k)); 779 // double p2 = double(4 * (k * k + 1) * (x0 * x0 + b * b + y0 * y0 - 2 * y0 * b - r * r)); 780 // return p2 - p1 >= 0; 781 } 782 783 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Declaring_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 784 785 inline void Input(); 786 787 inline void Solve(); 788 789 inline void Output(); 790 791 inline void Add_Ants(); 792 793 inline int Move_Ants(); 794 795 inline void New_Round(); 796 797 inline void Start_Round(); 798 799 inline void Pre_Treat_Tower(); 800 801 inline void End_Round(); 802 803 inline void Cal_Tar(); 804 805 inline void Attack(int); 806 807 inline void Dec_Health(); 808 809 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Main_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 810 811 812 int main(){ 813 Main_Init(); 814 Input(); 815 Solve(); 816 Output(); 817 return 0; 818 } 819 820 821 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Function_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 822 823 inline void Input(){ 824 N = read() + 1, M = read() + 1, S = read(), D = read(), R = read(); 825 for(int i = 1; i <= S; i++){ 826 Towers[i].x = read() + 1, Towers[i].y = read() + 1; 827 } 828 T = read(); 829 } 830 831 inline void Add_Ants(){ 832 A In; 833 ++tot; 834 In.Birth = Time, In.Level = (tot - 1) / 6 + 1, In.Health = Pow[In.Level], In.Survival = 1, In.Cake = false; 835 In.Death = false; 836 In.LPos = In.Pos = P<int, int>(1, 1); 837 Ants.push_back(In); 838 } 839 840 inline void Pre_Treat_Tower(){ 841 for(int k = 1; k <= S; k++){ 842 int x = Towers[k].x, y = Towers[k].y; 843 Ori[x][y] = true; 844 for(int i = 1; i <= N; i++){ 845 for(int j = 1; j <= M; j++){ 846 if(Get_Dis(x, y, i, j) <= R){ 847 In_Tower[i][j].push_back(k); 848 } 849 } 850 } 851 /* 852 Ori[x][y] = true; 853 for(int j = 0; j < R; j++){ 854 int x0 = x - R + j, x1 = x + R - j; 855 int ys = y - j; 856 for(int k = 1; k <= (j << 1) + 1; k++){ 857 if(ys + k - 1 <= 0 || ys + k - 1 > M) continue; 858 if(x0 > 0 && x0 <= N) 859 In_Tower[x0][ys + k - 1].push_back(i); 860 if(x1 > 0 && x1 <= N) 861 In_Tower[x1][ys + k - 1].push_back(i); 862 } 863 } 864 for(int j = y - R; j <= y + R; j++) 865 In_Tower[x][j].push_back(i);*/ 866 } 867 } 868 869 inline int Move_Ants(){ 870 int cake = 0; 871 for(int i = 1; i <= Ant; i++){//不知道要不要移走出生点的 872 // if(Pross[i] -> Birth == Time) continue; 873 int x = (Pross[i] -> Pos).x, y = (Pross[i] -> Pos).y, Dir = 4, Max_D = 0; 874 Forbid[x][y] = false; 875 for(int j = 0; j < 4; j++){ 876 int tx = x + Step_CXX[j][0], ty = y + Step_CXX[j][1]; 877 if(Forbid[tx][ty] || (tx == Pross[i] -> LPos.x && ty == Pross[i] -> LPos.y)) continue; 878 if(Dir == 4 || Pher[tx][ty] > Max_D) Max_D = Pher[tx][ty], Dir = j; 879 } 880 if(Dir != 4){ 881 if(Pross[i] -> Survival % 5 == 0){ 882 for(int j = 1; j < 4; j++){ 883 int k = (Dir - j + 4) % 4; 884 int tx = x + Step_CXX[k][0], ty = y + Step_CXX[k][1]; 885 if(!Forbid[tx][ty] && (tx != Pross[i] -> LPos.x || ty != Pross[i] -> LPos.y)){//逻辑运算 886 Dir = k; 887 break; 888 } 889 } 890 } 891 } 892 Pross[i] -> LPos.x = x, Pross[i] -> LPos.y = y; 893 (Pross[i] -> Pos).x = x = x + Step_CXX[Dir][0], (Pross[i] -> Pos).y = y = y + Step_CXX[Dir][1]; 894 Forbid[x][y] = true; 895 if(x == N && y == M && Is_Cake){ 896 Pross[i] -> Health = min(Pow[Pross[i] -> Level], Pross[i] -> Health + (Pow[Pross[i] -> Level] >> 1)); 897 Pross[i] -> Cake = true, cake = i, Is_Cake = false; 898 } 899 } 900 return cake; 901 } 902 903 inline void Start_Round(){ 904 Time++; 905 memcpy(Forbid, Ori, sizeof(Forbid)); 906 for(list<A>::iterator it = Ants.begin(); it != Ants.end(); it++){ 907 Forbid[it -> Pos.x][it -> Pos.y] = true; 908 } 909 if(Ants.size() < 6 && !Forbid[1][1]) 910 Add_Ants(), Forbid[1][1] = true; 911 Ant = 0; 912 for(list<A>::iterator it = Ants.begin(); it != Ants.end(); it++){ 913 Pross[++Ant] = it; 914 Pher[Pross[Ant] -> Pos.x][Pross[Ant] -> Pos.y] += 2 + Pross[Ant] -> Cake * 3; 915 } 916 } 917 918 inline void End_Round(){ 919 for(list<A>::iterator it = Ants.begin(); it != Ants.end(); it++){ 920 if(!it -> Death && it -> Cake && it -> Pos.x == 1 && it -> Pos.y == 1){ 921 Game_State = GO; 922 return ; 923 } 924 } 925 for(list<A>::iterator it = Ants.begin(); it != Ants.end(); it++){ 926 it -> Survival++; 927 } 928 for(int i = 1; i <= N; i++){ 929 for(int j = 1; j <= M; j++){ 930 Pher[i][j] = max(Pher[i][j] - 1, 0); 931 } 932 } 933 } 934 935 inline void Attack(int Cake_Tar){ 936 for(int i = 1; i <= S; i++){ 937 Tower[i].Target = 0; 938 Tower[i].In_T.clear(); 939 } 940 for(int i = 1; i <= Ant; i++){ 941 int x = Pross[i] -> Pos.x, y = Pross[i] -> Pos.y, size = In_Tower[x][y].size(); 942 // printf("In Time %d, %d on (%d, %d) With %d Who born in %d\n", Time, i, x, y, Pross[i] -> Health, Pross[i] -> Birth); 943 for(int j = 0; j < size; j++){ 944 int tar = In_Tower[x][y][j]; 945 Tower[tar].In_T.push_back(P<int, double>(i, Get_Dis(x, y, Towers[tar].x, Towers[tar].y))); 946 if(Pross[i] -> Cake) Tower[tar].Target = i; 947 } 948 } 949 // printf("%d %d\n", Pross[1] -> Pos.x, Pross[1] -> Pos.y); 950 // Print_List(Tower[1].In_T.begin(), Tower[1].In_T.end(), "In_T"); 951 for(int i = 1; i <= S; i++){ 952 if(Tower[i].Target) goto Att_Label; 953 if(Tower[i].In_T.empty()) continue; 954 sort(Tower[i].In_T.begin(), Tower[i].In_T.end(), cmp); 955 Tower[i].Target = Tower[i].In_T.front().x; 956 Att_Label:for(auto j = Tower[i].In_T.begin(); j != Tower[i].In_T.end(); j++){ 957 // double Debug = j -> y; 958 if(j -> x == Tower[i].Target || 959 Can_Be_Hit(Towers[i].x - 1, Towers[i].y - 1, Pross[j -> x] -> Pos.x - 1, Pross[j -> x] -> Pos.y - 1, Pross[Tower[i].Target] -> Pos.x - 1, Pross[Tower[i].Target] -> Pos.y - 1)){ 960 Pross[j -> x] -> Health -= D; 961 // printf("In Time %d, %d on (%d, %d) Was Attacked by %d\n", Time, j -> x, Pross[j -> x] -> Pos.x, Pross[j -> x] -> Pos.y, i); 962 } 963 } 964 } 965 for(int i = 1; i <= Ant; i++){ 966 if(Pross[i] -> Health < 0){ 967 Pross[i] -> Death = true; 968 if(Pross[i] -> Cake) Is_Cake = true; 969 } 970 } 971 bool flag = true; 972 while(flag){ 973 flag = false; 974 for(list<A>::iterator it = Ants.begin(); it != Ants.end(); it++){ 975 if(it -> Death){ 976 flag = true; 977 Ants.erase(it); 978 break; 979 } 980 } 981 } 982 } 983 984 inline void New_Round(){ 985 Start_Round(); 986 Attack(Move_Ants()); 987 End_Round(); 988 } 989 990 inline void Solve(){//整理事件是个不错的方法 991 Can_Be_Hit(1, 3, 0, 4, 0, 3); 992 Pre_Treat_Tower(); 993 for(int i = 0; i <= M; i++) Ori[0][i] = Ori[N + 1][i] = true; 994 for(int i = 0; i <= N; i++) Ori[i][0] = Ori[i][M + 1] = true; 995 double pow11[233]; 996 pow11[0] = 1; 997 for(int i = 1; i <= 200; i++){ 998 pow11[i] = pow11[i - 1] * 1.1; 999 Pow[i] = pow11[i] * 4; 1000 } 1001 while(Time < T && Game_State == ING) 1002 New_Round(); 1003 } 1004 1005 inline void Output(){ 1006 if(Time < T || Game_State == GO) printf("Game over after %d seconds\n", Time); 1007 else puts("The game is going on"); 1008 printf("%d\n", Ants.size()); 1009 Ants.sort(); 1010 for(auto it : Ants){ 1011 printf("%d %d %d %d %d\n", it.Survival - 1, it.Level, it.Health, it.Pos.x - 1, it.Pos.y - 1); 1012 } 1013 }
我永远爱19491001