记录编号 457758 评测结果 AAAAAAAAAA
题目名称 [ZJOI 2008] 杀蚂蚁 (完整版) 最终得分 100
用户昵称 GravatarAnonymity 是否通过 通过
代码语言 C++ 运行时间 0.283 s
提交时间 2017-10-09 11:51:00 内存使用 0.69 MiB
显示代码纯文本
#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;
}