[ZJOI 2008] 杀蚂蚁 (完整版)

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1033

没话可说,模拟吧骚年,判断在不在一条线上有点恶心,其他处理还好

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <cmath>
  6 using namespace std;
  7 #define eps 1e-9
  8 int Map[9][9],s,d,t,r,n,m,tot,antcnt,Infor[9][9],cake,T;
  9 int dx[5]={-1,0,1,0},dy[5]={0,-1,0,1};
 10 struct GUN{int x,y;} gun[25];
 11 double qx[200005];
 12 bool End;
 13 int dcmp(double x) {
 14     if (x<=eps&&x>=-eps) return 0;
 15     return (x>0)?1:-1;
 16 }
 17 struct ANT {
 18     int x,y,lastx,lasty,age,level,startblood,blood;
 19     bool carry;
 20 } ant[10];
 21 struct Point {
 22     double x,y;
 23     Point(double X=0,double Y=0) {x=X,y=Y;}
 24 };
 25 Point operator + (Point a,Point b) {return Point(a.x+b.x,a.y+b.y);}
 26 Point operator - (Point a,Point b) {return Point(a.x-b.x,a.y-b.y);}
 27 bool operator == (Point a,Point b) {return a.x==b.x&&a.y==b.y;}
 28 double Dot(Point a,Point b){return a.x*b.x+a.y*b.y;}
 29 double Cross(Point a,Point b){return a.x*b.y-a.y*b.x;}
 30 double Len(Point a){return sqrt(a.x*a.x+a.y*a.y);}
 31 double DisTS(Point P,Point A,Point B) {
 32     if (A==B) return Len(P-A);
 33     Point v=B-A,w=P-A,u=P-B;
 34     if (dcmp(Dot(v,w))<0) return Len(w);
 35     else if (dcmp(Dot(v,u))>0) return Len(u);
 36     else return fabs(Cross(v,w)/Len(v));
 37 }
 38 void Birth() {
 39     if(antcnt<6&&!Map[0][0]) {
 40         ++antcnt,++tot,++Map[0][0];
 41         ant[antcnt].x=ant[antcnt].y=ant[antcnt].lastx=ant[antcnt].lasty=0;
 42         ant[antcnt].age=1,ant[antcnt].level=(tot-1)/6+1;
 43         ant[antcnt].startblood=ant[antcnt].blood=floor(4*qx[ant[antcnt].level]);
 44         ant[antcnt].carry=false;
 45     }
 46 }
 47 void Add_Information() {
 48     for (int i=1; i<=antcnt; ++i) {
 49         if (ant[i].carry) Infor[ant[i].x][ant[i].y]+=5;
 50         else Infor[ant[i].x][ant[i].y]+=2;
 51     }
 52 }
 53 void Carry() {
 54     if(cake) return ;
 55     for(int i=1; i<=antcnt; ++i) {
 56         if(ant[i].x==n&&ant[i].y==m) {
 57             ant[i].carry=true,cake=i;
 58             ant[i].blood+=ant[i].startblood/2;
 59             ant[i].blood=min(ant[i].blood,ant[i].startblood);
 60             break;
 61         }
 62     }
 63 }
 64 void CheckDeath() {
 65     int i=1;
 66     while(i<=antcnt) {
 67         if(ant[i].blood<0) {
 68             --Map[ant[i].x][ant[i].y];
 69             for(int j=i; j<antcnt; ++j) ant[j]=ant[j+1];
 70             --antcnt;
 71         } else ++i;
 72     } cake=0;
 73     for(i=1; i<=antcnt; ++i) {
 74         if (ant[i].carry) {
 75             cake=i;
 76             break;
 77         }
 78     }
 79 }
 80 bool Check_end() {
 81     if(!cake) return false;
 82     for(int i=1; i<=antcnt; ++i) if(!ant[i].x&&!ant[i].y&&ant[i].carry) return true;
 83     return false;
 84 }
 85 void Change() {
 86     for(int i=0; i<=n; ++i) {
 87         for(int j=0; j<=m; ++j) if(Infor[i][j]) --Infor[i][j];
 88     }
 89     for(int i=1; i<=antcnt; ++i) ++ant[i].age;
 90 }
 91 void Move() {
 92     for(int dir=0,i=1,Max=0,canmove=0; i<=antcnt; ++i,Max=0,canmove=0,dir=0) {
 93         int x=ant[i].x,y=ant[i].y;
 94         int lastx=ant[i].lastx,lasty=ant[i].lasty;
 95         bool move[4]={0};
 96         memset(move,0,sizeof(move));
 97         for(int j=0; j<4; ++j) {
 98             int nxtx=x+dx[j],nxty=y+dy[j];
 99             if(nxtx>=0&&nxtx<=n&&nxty>=0&&nxty<=m&&!Map[nxtx][nxty]&&(nxtx!=lastx||nxty!=lasty)) {
100                 move[j]=1;
101                 ++canmove;
102                 Max=max(Max,Infor[nxtx][nxty]);
103             }
104         }
105         if(!canmove) {ant[i].lastx=x;ant[i].lasty=y;continue;}
106         for(int j=3; j>=0; --j) {
107             int nxtx=x+dx[j],nxty=y+dy[j];
108             if(move[j]&&Infor[nxtx][nxty]==Max) {
109                 dir=j;
110                 if(ant[i].age%5==0) break;
111                 --Map[x][y],++Map[nxtx][nxty];
112                 ant[i].lastx=x,ant[i].lasty=y;
113                 ant[i].x=nxtx,ant[i].y=nxty;
114                 break;
115             }
116         }
117         if(!(ant[i].age%5)) {
118             for(int j=0; j<4; ++j) {
119                 ++dir;
120                 if(dir==4) dir=0;
121                 if(move[dir]) {
122                     int nxtx=x+dx[dir],nxty=y+dy[dir];
123                     --Map[x][y];
124                     ++Map[nxtx][nxty];
125                     ant[i].lastx=x,ant[i].lasty=y;
126                     ant[i].x=nxtx,ant[i].y=nxty;
127                     break;
128                 }
129             }
130         }
131     }
132 }
133 int len(ANT a,GUN b) {return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}
134 int get_goal(int x) {
135     int goal=0,Min=0x3f3f3f3f;
136     if(cake&&len(ant[cake],gun[x])<=r*r) return cake;
137     for(int now,i=1; i<=antcnt; ++i) {
138         now=len(ant[i],gun[x]);
139         if(now<=r*r&&now<Min) Min=now,goal=i;
140     } return goal;
141 }
142 bool canhit(ANT a,GUN b,ANT c) {
143     Point A=Point(b.x,b.y);
144     Point B=Point(c.x,c.y);
145     Point P=Point(a.x,a.y);
146     double dis=DisTS(P,A,B);
147     if (dcmp(dis-0.5)<=0) return 1;
148     else return 0;
149 }
150 void Attack() {
151     for(int goal=0,i=1; i<=s; ++i,goal=0) {
152         goal=get_goal(i);
153         if(!goal) continue;
154         for(int j=1; j<=antcnt; ++j) {
155             if(canhit(ant[j],gun[i],ant[goal])) ant[j].blood-=d;
156         }
157     }
158 }
159 int main() {
160     freopen("antbuster_ex.in","r",stdin);
161     freopen("antbuster_ex.out","w",stdout);
162     scanf("%d%d",&n,&m);
163     scanf("%d%d%d",&s,&d,&r);
164     for(int i=1; i<=s; ++i) scanf("%d%d",&gun[i].x,&gun[i].y),Map[gun[i].x][gun[i].y]=-1;
165     scanf("%d",&t);
166     qx[0]=1; for(int i=1; i<=t; ++i) qx[i]=qx[i-1]*1.1;
167     for(T=1; T<=t; ++T) {
168         Birth();
169         Add_Information();
170         Move();
171         Carry();
172         Attack();
173         CheckDeath();
174         if(End=Check_end()) break;
175         Change();
176     }
177     if(End) printf("Game over after %d seconds\n%d\n",T,antcnt);
178     else printf("The game is going on\n%d\n",antcnt);
179     for(int i=1; i<=antcnt; ++i) printf("%d %d %d %d %d\n",ant[i].age-1,ant[i].level,ant[i].blood,ant[i].x,ant[i].y);
180     return 0;
181 }

 

posted @ 2017-10-17 06:27  Forever_goodboy  阅读(442)  评论(0编辑  收藏  举报