【BZOJ1033】[ZJOI2008]杀蚂蚁antbuster【模拟】

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define FOREACH if(cnt)for(int i=hed;i;i=ants[i].nxt)
using namespace std;

const int MX=250,MXT=200050,inf=0x3f3f3f3f;

const int dx[5]={0,0,1,0,-1},dy[5]={0,1,0,-1,0};
int mxhp[MX];
int n,m,s,d,r,t;
int x[MX],y[MX];
int f[MX][MX];
bool ava[MX][MX];
int hed,tai,antc,cnt,cur,target;
struct ant* ants;
struct ant{
	int x,y,lstx,lsty,hp,lvl,pre,nxt,bornt;
	inline void creat()
	{
		ant res;
		res.lstx=res.lsty=-1;
		res.lvl=antc/6+1;
		res.bornt=cur;
		res.hp=mxhp[res.lvl];
		res.x=res.y=0;
		res.pre=tai;res.nxt=0;
		ants[++antc]=res;
		ants[tai].nxt=antc;
		tai=antc;
		if(!cnt)hed=antc;
		cnt++;
		ava[0][0]=false;
	}
	inline void addf()
	{
		f[x][y]+=((target==this-ants)?5:2);
	}
	inline bool ck()
	{
		return (!x&&!y&&(target==this-ants));
	}
	inline bool ckdead()
	{
		if(hp<0)
		{
			if(target==this-ants)target=0;
			cnt--;
			if(hed==this-ants)hed=nxt;else ants[pre].nxt=nxt;
			if(tai==this-ants){tai=pre;ants[tai].nxt=0;}else ants[nxt].pre=pre;
			ava[x][y]=true;
		}
		return hp<0;
	}
	inline void getck()
	{
		if(!target&&x==n&&y==m)
		{
			target=this-ants;
			hp=min(hp+(mxhp[lvl]>>1),mxhp[lvl]);
		}
	}
	inline void mov()
	{
		int chose=0,mxf=-1;
		int xx,yy;
		for(int i=1;i<=4;i++)
		{
			xx=x+dx[i],yy=y+dy[i];
			if(!(xx==lstx&&yy==lsty)&&xx>=0&&yy>=0&&xx<=n&&yy<=m&&ava[xx][yy]&&f[xx][yy]>mxf)
			{
				chose=i;
				mxf=f[xx][yy];
			}
		}
		if(chose&&(cur-bornt+1)%5==0)
		{
			for(int i=3;i>=0;i--)
			{
				int tmp=(chose+i-1)%4+1;
				xx=x+dx[tmp],yy=y+dy[tmp];
				if(!(xx==lstx&&yy==lsty)&&xx>=0&&yy>=0&&xx<=n&&yy<=m&&ava[xx][yy])
				{
					chose=tmp;break;
				}
			}
		}
		lstx=x,lsty=y;
		if(chose)
		{
			xx=x+dx[chose],yy=y+dy[chose];
			ava[x][y]=true;
			x=xx,y=yy;
			ava[x][y]=false;
		}
	}
}pool[MXT],null;


void rd()
{
	scanf("%d%d%d%d%d",&n,&m,&s,&d,&r);
	for(int i=1;i<=s;i++)scanf("%d%d",&x[i],&y[i]);
	scanf("%d",&t);
}
void ini()
{
	ants=pool;
	for(int i=1;i<=200;i++)
	{
		mxhp[i]=floor(4.0*pow(1.1,(double)i));
	}
	memset(ava,true,sizeof(ava));
	for(int i=1;i<=s;i++)ava[x[i]][y[i]]=false;
}
#define DIS(i) ((x[j]-ants[i].x)*(x[j]-ants[i].x)+(y[j]-ants[i].y)*(y[j]-ants[i].y))
#define S (abs(xx*y[j]+ty*x[j]+tx*yy-yy*x[j]-xx*ty-tx*y[j]))
void atk()
{
	for(int j=1;j<=s;j++)
	{
		int tg=0;
		if(target&&DIS(target)<=r*r)tg=target;
		if(!tg)
		{
			int mndis=inf;
			FOREACH{
				int dis=DIS(i);
				if(dis<mndis&&dis<=r*r){
					mndis=dis;tg=i;
				}
			}
		}
		if(tg)
		{
			int tx=ants[tg].x,ty=ants[tg].y;
			int dis3=DIS(tg);
			FOREACH{
				int xx=ants[i].x,yy=ants[i].y;
				int dis1=(xx-tx)*(xx-tx)+(yy-ty)*(yy-ty),dis2=DIS(i);
				if(dis1+dis3>=dis2&&dis3+dis2>=dis1&&(4*S*S)<=dis3)
				ants[i].hp-=d;
			}
		}
	}
}
bool wk()
{
	for(cur=1;cur<=t;cur++)
	{
		if(cnt<6&&ava[0][0])null.creat();
		FOREACH{ants[i].addf();}
		FOREACH{ants[i].mov();}
		FOREACH{ants[i].getck();}
		atk();
		FOREACH{ants[i].ckdead();}
		FOREACH{
			if(ants[i].ck()){return false;}
		}
		for(int i=0;i<=n;i++)for(int j=0;j<=m;j++)f[i][j]=max(f[i][j]-1,0);
	}
	cur--;
	return true;
}
int main()
{
	rd();
	ini();
	bool aliv = wk();
	if(!aliv)printf("Game over after %d seconds\n",cur);
	else printf("The game is going on\n");
	printf("%d\n",cnt);
	FOREACH{printf("%d %d %d %d %d\n",cur-ants[i].bornt+(aliv?1:0),ants[i].lvl,ants[i].hp,ants[i].x,ants[i].y);}
	return 0;
}

注意事项:

1 蚂蚁有大小,并且直径是1(不是半径)

2 蚂蚁是先计算全部信息素,再全部移动,后面的蚂蚁留下信息素在前面的蚂蚁移动之前

3 age可以不存,链式存储就好了

4 直接维护信息素的值就好了

5 分清计算的乘号和加号(坑了1个小时qaq

6 炮塔是一起攻击的,所以就算某只蚂蚁的血被打成了负,还是要被攻击。

7 封装大法好

8 最好不要double,通分一下用int就好了


参考:

http://blog.csdn.net/braketbn/article/details/50813144

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值