• 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 ++ = '
    ';
     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
    ", 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
    ", 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
    ", 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
    ", Time);
    1007     else puts("The game is going on");
    1008     printf("%d
    ", Ants.size());
    1009     Ants.sort();
    1010     for(auto it : Ants){
    1011         printf("%d %d %d %d %d
    ", it.Survival - 1, it.Level, it.Health, it.Pos.x - 1, it.Pos.y - 1);
    1012     }
    1013 }
    Source Code
  • 相关阅读:
    【网络流24题】方格取数问题(最大流)
    运维之思科篇——NAT基础配置
    NAT地址转换常用命令详解
    NAT(地址转换技术)详解
    Linux命令之grep用法详解:grep与正则表达式 [转]
    curl查询公网出口IP
    CentOS下安装Telnet服务
    Linux之Xinetd服务介绍
    上市公司年报发布时间是什么时候?
    jackson序列化字段字母大小写及字段名重复
  • 原文地址:https://www.cnblogs.com/CreeperLKF/p/9247715.html
Copyright © 2020-2023  润新知