[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 }