Luogu2586 [ZJOI2008]杀蚂蚁 ---- 模拟

Luogu2586 [ZJOI2008]杀蚂蚁

题意

还是一道大模拟

https://www.luogu.org/problemnew/show/P2586

大概就是炮塔大蚂蚁的故事

下载这个游戏http://www.antbuster.net/Antbuster_12k_20090824.swf

还是比较难玩的

题解

就是预处理塔能打到的位置,然后直接把一局游戏分成几个阶段,同时每个阶段做了什么事也比较清楚,然后思路就比较清晰

一些经验:

  1. 尽量预处理一些静态的东西,然后不要临时算,这样会把整个函数弄得比较杂乱
  2. 容器什么的其实在Linux内是可以直接查看的,但是依然推荐通过运行输出查看,因为这样有一个跟踪容器变化的效果
  3. 每次更改代码之后记录一下改了什么地方,或者是版本控制
  4. 逻辑错误GDB不可行
  5. 然后这次精简了一些函数,可能对于整体效果来说还是比较可以的
   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 }
Source Code
posted @ 2018-06-30 16:33  Creeper_LKF  阅读(280)  评论(0编辑  收藏  举报