显示代码纯文本
#include <cstdio>
#include <algorithm>
inline void read(int& x)
{ char c=getchar();x=0;int y=1;
while(c<'0'||c>'9'){if(c=='-') y=-1;c=getchar();}
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
x*=y;
}
const int dx[6]={1,0,-1,0},dy[6]={0,-1,0,1};
template<typename T>inline void V_max(T& x,T y){if(x<y) x=y;}
template<typename T>inline void V_min(T& x,T y){if(x>y) x=y;}
template<typename T>inline T m_min(T x,T y){return x<y?x:y;}
double xp[33340];
int T,n,m,S,D,R,Range,LIFE[33340],Antsum,Bornsum,MAP[12][12];
bool Global_Cake=1,object[12][12],Over;
struct point{int x,y,z;point(int x=0,int y=0,int z=-1):x(x),y(y),z(z){}};
inline int Dist(int x,int y,int a,int b){return (x-a)*(x-a)+(y-b)*(y-b);}
struct Ant
{ int posx,posy,age,level,HP,lasdirect,feedback;
bool carry;
Ant(int x=0,int y=0,int z=1):posx(x),posy(y),age(1),level(z),HP(LIFE[z]),carry(0),feedback(-1),lasdirect(-1){}// pay attention to HP!!!
// the beginning age is 1 echo to time !!
inline void set_newpos(int x,int y,int z)
{ object[this->posx][this->posy]=0;this->feedback=this->lasdirect;
this->posx=x;this->posy=y;this->lasdirect=z;
object[x][y]=1;
}
inline void leave_pheromone()
{ if(this->carry) MAP[this->posx][this->posy]+=5;
else MAP[this->posx][this->posy]+=2;
}
inline int move()
{ point tmp[6];int stlen=0;// east 2 west 4 north 1 south 3
if(this->posx+1<=n&&!object[this->posx+1][this->posy]&&lasdirect!=0)
tmp[++stlen]=point(this->posx+1,this->posy,2);
if(this->posx-1>=0&&!object[this->posx-1][this->posy]&&lasdirect!=2)
tmp[++stlen]=point(this->posx-1,this->posy,0);
if(this->posy+1<=m&&!object[this->posx][this->posy+1]&&lasdirect!=3)
tmp[++stlen]=point(this->posx,this->posy+1,1);
if(this->posy-1>=0&&!object[this->posx][this->posy-1]&&lasdirect!=1)
tmp[++stlen]=point(this->posx,this->posy-1,3);
if(stlen==0){this->lasdirect=-1;return -1;}
if(stlen==1)
{ this->set_newpos(tmp[stlen].x,tmp[stlen].y,tmp[stlen].z);
return tmp[stlen].z;
}
int tmax=0;point tmp2[5];int len2=0;
for(int i=1;i<=stlen;++i) V_max(tmax,MAP[tmp[i].x][tmp[i].y]);
for(int i=1;i<=stlen;++i)
if(tmax==MAP[tmp[i].x][tmp[i].y]) tmp2[++len2]=tmp[i];
if(len2==1)
{ this->set_newpos(tmp2[len2].x,tmp2[len2].y,tmp2[len2].z);
return tmp2[len2].z;
}
if(len2>1)
{ int Judge=0,temp=1,aimx,aimy;
while(1)
{ aimx=this->posx-dx[temp];aimy=this->posy-dy[temp];
for(int i=1;i<=len2;++i)
if(tmp2[i].x==aimx&&tmp2[i].y==aimy){Judge=i;break;}
if(Judge){this->set_newpos(aimx,aimy,tmp2[Judge].z);return tmp2[Judge].z;}
temp=(temp+1)%4;
}
}
}
inline void special_move()
{ int direct=this->move();point tmp;int t2=-1;
if(feedback==1) t2=3;if(feedback==3) t2=1;
if(feedback==0) t2=2;if(feedback==2) t2=0;
if(direct==-1) return;
object[this->posx][this->posy]=0;
this->posx+=dx[direct];this->posy+=dy[direct];
object[this->posx][this->posy]=1;
while(1)
{ direct=(direct-1+4)%4;
tmp=point(this->posx-dx[direct],this->posy-dy[direct]);
if(direct!=t2&&tmp.x>=0&&tmp.x<=n&&tmp.y>=0&&tmp.y<=m&&!object[tmp.x][tmp.y])
{ this->set_newpos(tmp.x,tmp.y,direct);return;}
}
}
inline void take_cake()
{ if(!Global_Cake) return;
Global_Cake=0;this->carry=1;
this->HP=m_min(HP+(LIFE[this->level]>>1),LIFE[this->level]);
}
}*ant[8];
inline bool cmp_HP(const Ant* a,const Ant* b){return a->HP>b->HP;}
inline bool cmp_age(const Ant* a,const Ant* b){return a->age>b->age;}
struct Tower
{ int x,y,target;
Tower(int a=0,int b=0):x(a),y(b),target(0){};
inline void special_attack(double a,double b,double c,int Sx,int Sy,int Tx,int Ty)
{ double denominator=a*a+b*b;
if(Sx<Tx) std::swap(Sx,Tx);if(Sy>Ty) std::swap(Sy,Ty);
for(int i=1;i<=Antsum;++i)
if(ant[i]->posx<=Sx&&ant[i]->posy>=Sy&&ant[i]->posx>=Tx&&ant[i]->posy<=Ty)
{ double t1=a*ant[i]->posx+b*ant[i]->posy+c;
if(t1*t1*4.0<=denominator) ant[i]->HP-=D;
}
}
inline void especial_attack(int x,int Sy,int Ty)
{ if(Sy>Ty) std::swap(Sy,Ty);
for(int i=1;i<=Antsum;++i)
if(ant[i]->posx==x&&ant[i]->posy>=Sy&&ant[i]->posy<=Ty)
ant[i]->HP-=D;
}
inline void attack()
{ if(!Global_Cake)
{ int dis=Dist(ant[this->target]->posx,ant[this->target]->posy,this->x,this->y);
if(dis<=Range)
{ if(ant[this->target]->posx==this->x)
{ this->especial_attack(this->x,this->y,ant[this->target]->posy);
return;
}
double t1=((double)ant[this->target]->posy-this->y)/((double)ant[this->target]->posx-this->x);
double t2=this->y-(double)this->x*t1;
this->special_attack(t1,-1,t2,this->x,this->y,ant[target]->posx,ant[target]->posy);
return;
}
}
int tmp=Range,single_dis[10],st[8],stlen=0;
for(int i=1;i<=Antsum;++i)
{ int now=Dist(ant[i]->posx,ant[i]->posy,this->x,this->y);
V_min(tmp,now);single_dis[i]=now;
}
for(int i=1;i<=Antsum;++i)
if(single_dis[i]==tmp)
{ if(ant[i]->posx==this->x)
{ this->especial_attack(this->x,this->y,ant[i]->posy);
break;
}
double t1=((double)ant[i]->posy-this->y)/((double)ant[i]->posx-this->x);
double t2=this->y-(double)this->x*t1;
this->special_attack(t1,-1,t2,this->x,this->y,ant[i]->posx,ant[i]->posy);
break;
}
}
}*tower[25];
inline void make_newant()
{ if(object[0][0]) return;
++Bornsum;++Antsum;
ant[Antsum]=new Ant(0,0,(Bornsum-1)/6+1);
object[0][0]=1;
}
inline bool ALL_move()
{ if(Antsum<6) make_newant();
std::sort(ant+1,ant+Antsum+1,cmp_age);
for(int i=1;i<=Antsum;++i) ant[i]->leave_pheromone();
for(int i=1;i<=Antsum;++i)
{ if(!(ant[i]->age%5)) ant[i]->special_move();
else ant[i]->move();
if(ant[i]->posx==n&&ant[i]->posy==m) ant[i]->take_cake();
if(ant[i]->carry)
for(int j=1;j<=S;++j) tower[j]->target=i;
}
for(int i=1;i<=S;++i) tower[i]->attack();
std::sort(ant+1,ant+Antsum+1,cmp_HP);
for(int i=Antsum;i>=1;--i)
if(ant[i]->HP<0)
{ if(ant[i]->carry) ant[i]->carry=0,Global_Cake=1;
object[ant[i]->posx][ant[i]->posy]=0;--Antsum;
delete ant[i];ant[i]=NULL;
}
else if(ant[i]->carry&&!ant[i]->posx&&!ant[i]->posy) return 0;
for(int i=0;i<=n;++i) for(int j=0;j<=m;++j) if(MAP[i][j]) --MAP[i][j];
for(int i=1;i<=Antsum;++i) ++ant[i]->age;
return 1;
}
inline void Pre()
{ read(n);read(m);read(S);read(D);read(R);int x=0,y=0;Range=R*R;
for(int i=1;i<=S;++i) read(x),read(y),tower[i]=new Tower(x,y),object[x][y]=1;
read(T);xp[0]=1;
for(int i=1,j=(T-1)/6+1;i<=j;++i) xp[i]=xp[i-1]*(double)1.1,LIFE[i]=(int)(4*xp[i]);
}
int main()
{ freopen("antbuster_ex.in","r",stdin);
freopen("antbuster_ex.out","w",stdout);
Pre();
for(int Clock=1;Clock<=T;++Clock)
if(!ALL_move())
{ Over=1;std::sort(ant+1,ant+Antsum+1,cmp_age);
printf("Game over after %d seconds\n",Clock);
printf("%d\n",Antsum);
for(int i=1;i<=Antsum;++i)
printf("%d %d %d %d %d\n",ant[i]->age-1,ant[i]->level,ant[i]->HP,ant[i]->posx,ant[i]->posy);
break;
}
if(!Over)
{ std::sort(ant+1,ant+Antsum+1,cmp_age);
printf("The game is going on\n");
printf("%d\n",Antsum);
for(int i=1;i<=Antsum;++i)
printf("%d %d %d %d %d\n",ant[i]->age-1,ant[i]->level,ant[i]->HP,ant[i]->posx,ant[i]->posy);
}
return 0;
}