# bzoj_1033: [ZJOI2008]杀蚂蚁antbuster

1.蚂蚁移动时，并不是只会向信息素最多的地方移动

2.蚂蚁被卡在(n,m) 时，忘了拿蛋糕了...

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
#define ll long long
#define dd double
#define ld long double
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int S=26;
const int TTT=200006;
const int N=12;
const dd esp=1e-10;
const int INF=0x7fffffff;
inline dd dis(int x3,int y3,int x4,int y4)
{
return sqrt( (y3-y4)*(y3-y4)+(x3-x4)*(x3-x4) );
}
struct Ant
{
int x,y,age,lev;
ll blood,bloodlimit;
int lasx,lasy;
bool cakeif;
Ant(){}
inline Ant(int xx,int yy,int agee,int levv,ll bloodd,int cakeiff)
{
x=xx;y=yy;age=agee;lev=levv;blood=bloodd;cakeif=cakeiff;
bloodlimit=bloodd;
lasx=-1;lasy=-1;
}
void out()
{
printf("%d %d %d %d %d %d\n",x,y,age,lev,blood,cakeif);
}
};

int n,m;
int s,d,r;
int x[S],y[S];
int T;
int ban[N][N];

inline void Init()
{
scanf("%d%d",&n,&m);
scanf("%d%d%d",&s,&d,&r);
for(int i=1;i<=s;++i)
{
scanf("%d%d",&x[i],&y[i]);
ban[x[i]][y[i]]=1;
}
scanf("%d",&T);
}

int xin[N][N];
Ant ji[N];int he;
int cnt;
int bx[10]={0,1,0,-1};
int by[10]={1,0,-1,0};
bool cake;

inline int callev(int ccc)
{
return (ccc-1)/6+1;
}

inline ll calblood(int ccc)
{
return (ll)(4*pow(1.1,callev(ccc)));
}

inline void leftxin()
{
for(int i=1;i<=he;++i)
xin[ji[i].x][ji[i].y]+=(ji[i].cakeif?5:2);
}

inline void walk(int order,int di)
{
ji[order].lasx=ji[order].x;ji[order].lasy=ji[order].y;
ji[order].x+=bx[di];ji[order].y+=by[di];
ban[ji[order].lasx][ji[order].lasy]=0;
ban[ji[order].x][ji[order].y]=1;
if(ji[order].x==n&&ji[order].y==m&&cake)
ji[order].cakeif=1,cake=0,ji[order].blood=min(ji[order].bloodlimit,ji[order].blood+ji[order].bloodlimit/2);
}
void out1(int order)
{
printf("order=%d age=%d x=%d y=%d\n",order,ji[order].age,ji[order].x,ji[order].y);
}

inline void move(int order)
{
int mn=-1,tx,ty;
for(int i=0;i<4;++i)
{
tx=ji[order].x+bx[i];ty=ji[order].y+by[i];
if(tx<0||tx>n||ty<0||ty>m||ban[tx][ty]||(tx==ji[order].lasx&&ty==ji[order].lasy))
continue;
if(mn<xin[tx][ty])
mn=xin[tx][ty];
}
if(mn==-1)
{
ji[order].lasx=ji[order].lasy=-1;
if(ji[order].x==n&&ji[order].y==m&&cake)
ji[order].cakeif=1,cake=0,ji[order].blood=min(ji[order].bloodlimit,ji[order].blood+ji[order].bloodlimit/2);
return ;
}
int di;
for(int i=0;i<4;++i)
{
tx=ji[order].x+bx[i];ty=ji[order].y+by[i];
if(tx<0||tx>n||ty<0||ty>m||ban[tx][ty]||(tx==ji[order].lasx&&ty==ji[order].lasy))
continue;
if(mn==xin[tx][ty])
{
di=i;
break;
}
}
if((ji[order].age+1)%5==0)
{
while(1)
{
di=(di+3)%4;
tx=ji[order].x+bx[di];ty=ji[order].y+by[di];
if(tx<0||tx>n||ty<0||ty>m||ban[tx][ty]||(tx==ji[order].lasx&&ty==ji[order].lasy))
continue;
break;
}
}
walk(order,di);
}

{
for(int i=1;i<=he;++i)
++ji[i].age;
}

inline void reducexin()
{
for(int i=0;i<=n;++i)
for(int j=0;j<=m;++j)
if(xin[i][j])
--xin[i][j];
}

inline void A(int order)
{
ji[order].blood-=d;
}

inline void checkdie()
{
int ttt=0;
for(int i=1;i<=he;++i)
{
if(ji[i].blood>=0)
ji[++ttt]=ji[i];
else
{
ban[ji[i].x][ji[i].y]=0;
if(ji[i].cakeif)
cake=1;
}
}
he=ttt;
}

inline int is_in(int ta,int aid,int order)
{
int lx=x[ta],ly=y[ta],rx=ji[aid].x,ry=ji[aid].y;
if(lx>rx)
swap(lx,rx),swap(ly,ry);
if(ji[order].x<lx||ji[order].x>rx)
return 0;
if(ji[order].y<min(ly,ry)||ji[order].y>max(ly,ry))
return 0;
dd A=0,B=0,C=0;
if(lx==rx)
A=1,B=0,C=-lx;
else
A=(dd)(ry-ly)/(rx-lx),B=-1.0,C=(dd)ly-(dd)lx*A;
if( fabs(A*ji[order].x+B*ji[order].y+C)/sqrt(A*A+B*B)<0.5+esp )
return 1;
return 0;
}

inline void attack(int order)
{
if(he==0)
return ;
int aid=-1,age=0;
dd distance=INF,dtemp;
for(int i=1;i<=he;++i)
{
dtemp=dis(x[order],y[order],ji[i].x,ji[i].y);
if(dtemp>r)
continue;
if( fabs(dtemp-distance)<esp )
{
if(age<ji[i].age)
{
aid=i;
age=ji[i].age;
}
}
else
if( distance+esp>dtemp )
{
aid=i;
distance=dtemp;
age=ji[i].age;
}
}
for(int i=1;i<=he;++i)
{
dtemp=dis(x[order],y[order],ji[i].x,ji[i].y);
if(dtemp>r)
continue;
if(ji[i].cakeif)
aid=i;
}
if(aid==-1)
return ;
A(aid);
for(int i=1;i<=he;++i)
{
if(i==aid||!is_in(order,aid,i))
continue;
A(i);
}
}

inline int check()
{
for(int i=1;i<=he;++i)
if(ji[i].x==0&&ji[i].y==0&&ji[i].cakeif)
return 1;
return 0;
}

void out(int x)
{
printf("Game over after %d seconds\n",x);
printf("%d\n",he);
for(int i=1;i<=he;++i)
printf("%d %d %lld %d %d\n",ji[i].age,ji[i].lev,ji[i].blood,ji[i].x,ji[i].y);
}

void outend()
{
printf("The game is going on\n");
printf("%d\n",he);
for(int i=1;i<=he;++i)
printf("%d %d %lld %d %d\n",ji[i].age,ji[i].lev,ji[i].blood,ji[i].x,ji[i].y);
}

inline void work()
{
cake=1;cnt=0;mem(xin,0);
for(int i=1;i<=T;++i)
{
if(he<6&&!ban[0][0])
{
++cnt;
ji[++he]=Ant(0,0,0,callev(cnt),calblood(cnt),0);
ban[0][0]=1;
}
leftxin();
for(int j=1;j<=he;++j)
move(j);
for(int j=1;j<=s;++j)
attack(j);
checkdie();
if(check())
{
out(i);
return ;
}
reducexin();
}
outend();
}
int main(){

//freopen("antbuster_ex.in","r",stdin);
//freopen("antbuster_ex.out","w",stdout);

//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);

Init();
work();
}

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
#define ll long long
#define dd double
#define ld long double
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int S=26;
const int TTT=200006;
const int N=12;
const dd esp=1e-10;
const int INF=0x7fffffff;
inline dd dis(int x3,int y3,int x4,int y4)
{
return sqrt( (y3-y4)*(y3-y4)+(x3-x4)*(x3-x4) );
}
struct Ant
{
int x,y,age,lev;
ll blood,bloodlimit;
int lasx,lasy;
bool cakeif;
Ant(){}
inline Ant(int xx,int yy,int agee,int levv,ll bloodd,int cakeiff)
{
x=xx;y=yy;age=agee;lev=levv;blood=bloodd;cakeif=cakeiff;
bloodlimit=bloodd;
lasx=-1;lasy=-1;
}
void out()
{
printf("%d %d %d %d %d %d\n",x,y,age,lev,blood,cakeif);
}
};

int n,m;
int s,d,r;
int x[S],y[S];
int T;
int ban[N][N];

inline void Init()
{
scanf("%d%d",&n,&m);
scanf("%d%d%d",&s,&d,&r);
for(int i=1;i<=s;++i)
{
scanf("%d%d",&x[i],&y[i]);
ban[x[i]][y[i]]=1;
//printf("x[i]=%d y[i]=%d\n",x[i],y[i]);
}
scanf("%d",&T);
}

int xin[N][N];
Ant ji[N];int he;
int cnt;
int bx[10]={0,1,0,-1};
int by[10]={1,0,-1,0};
bool cake;

inline int callev(int ccc)
{
return (ccc-1)/6+1;
}

inline ll calblood(int ccc)
{
return (ll)(4*pow(1.1,callev(ccc)));
}

inline void leftxin()
{
for(int i=1;i<=he;++i)
xin[ji[i].x][ji[i].y]+=(ji[i].cakeif?5:2);
}

inline void walk(int order,int di)
{
ji[order].lasx=ji[order].x;ji[order].lasy=ji[order].y;
ji[order].x+=bx[di];ji[order].y+=by[di];
ban[ji[order].lasx][ji[order].lasy]=0;
ban[ji[order].x][ji[order].y]=1;
if(ji[order].x==n&&ji[order].y==m&&cake)
ji[order].cakeif=1,cake=0,ji[order].blood=min(ji[order].bloodlimit,ji[order].blood+ji[order].bloodlimit/2);
}
//printf("%d %d %d %d %d %d\n",x,y,age,lev,blood,cakeif);
void out1(int order)
{
printf("order=%d age=%d x=%d y=%d\n",order,ji[order].age,ji[order].x,ji[order].y);
}

inline void move(int order)//不能只是保存信息素最多的方向，其他少的也可以走...
{
int mn=-1,tx,ty;
for(int i=0;i<4;++i)
{
tx=ji[order].x+bx[i];ty=ji[order].y+by[i];
if(tx<0||tx>n||ty<0||ty>m||ban[tx][ty]||(tx==ji[order].lasx&&ty==ji[order].lasy))
continue;
if(mn<xin[tx][ty])
mn=xin[tx][ty];
}
if(mn==-1)// 忘拿蛋糕了....
{
ji[order].lasx=ji[order].lasy=-1;
if(ji[order].x==n&&ji[order].y==m&&cake)
ji[order].cakeif=1,cake=0,ji[order].blood=min(ji[order].bloodlimit,ji[order].blood+ji[order].bloodlimit/2);
return ;
}
int di;
for(int i=0;i<4;++i)
{
tx=ji[order].x+bx[i];ty=ji[order].y+by[i];
if(tx<0||tx>n||ty<0||ty>m||ban[tx][ty]||(tx==ji[order].lasx&&ty==ji[order].lasy))
continue;
if(mn==xin[tx][ty])
{
di=i;
break;
}
}
if((ji[order].age+1)%5==0)
{
while(1)
{
di=(di+3)%4;
tx=ji[order].x+bx[di];ty=ji[order].y+by[di];
if(tx<0||tx>n||ty<0||ty>m||ban[tx][ty]||(tx==ji[order].lasx&&ty==ji[order].lasy))
continue;
break;
}
}
walk(order,di);
}

{
for(int i=1;i<=he;++i)
++ji[i].age;
}

inline void reducexin()
{
for(int i=0;i<=n;++i)
for(int j=0;j<=m;++j)
if(xin[i][j])
--xin[i][j];
}

inline void A(int order)
{
ji[order].blood-=d;
}

inline void checkdie()
{
int ttt=0;
for(int i=1;i<=he;++i)
{
if(ji[i].blood>=0)
ji[++ttt]=ji[i];
else
{
ban[ji[i].x][ji[i].y]=0;
if(ji[i].cakeif)
cake=1;
}
}
he=ttt;
}

inline int is_in(int ta,int aid,int order)
{
int lx=x[ta],ly=y[ta],rx=ji[aid].x,ry=ji[aid].y;
//printf("lx=%d ly=%d rx=%d ry=%d ",lx,ly,rx,ry);
if(lx>rx)
swap(lx,rx),swap(ly,ry);
if(ji[order].x<lx||ji[order].x>rx)
return 0;
if(ji[order].y<min(ly,ry)||ji[order].y>max(ly,ry))
return 0;
dd A=0,B=0,C=0;
if(lx==rx)
A=1,B=0,C=-lx;
else
A=(dd)(ry-ly)/(rx-lx),B=-1.0,C=(dd)ly-(dd)lx*A;
//printf("lx=%d ly=%d rx=%d ry=%d aid=%d A=%lf B=%lf C=%lf\n",lx,ly,rx,ry,aid,A,B,C);
if( fabs(A*ji[order].x+B*ji[order].y+C)/sqrt(A*A+B*B)<0.5+esp )
return 1;
return 0;
}

inline void attack(int order)
{
if(he==0)
return ;
int aid=-1,age=0;
dd distance=INF,dtemp;
for(int i=1;i<=he;++i)
{
dtemp=dis(x[order],y[order],ji[i].x,ji[i].y);
if(dtemp>r)
continue;
if( fabs(dtemp-distance)<esp )
{
if(age<ji[i].age)
{
aid=i;
age=ji[i].age;
}
}
else
if( distance+esp>dtemp )
{
aid=i;
distance=dtemp;
age=ji[i].age;
}
}
for(int i=1;i<=he;++i)
{
dtemp=dis(x[order],y[order],ji[i].x,ji[i].y);
if(dtemp>r)
continue;
if(ji[i].cakeif)
{
//printf("now????\n");
aid=i;
}
}
if(aid==-1)
return ;
//printf("tax=%d tay=%d aidx=%d aidy=%d\n",x[order],y[order],ji[aid].x,ji[aid].y);
A(aid);
for(int i=1;i<=he;++i)
{
if(i==aid||!is_in(order,aid,i))
continue;
//printf("tax=%d tay=%d aid=%d i=%d 好疼啊\n",x[order],y[order],aid,i);
A(i);
}
}

inline int check()
{
for(int i=1;i<=he;++i)
if(ji[i].x==0&&ji[i].y==0&&ji[i].cakeif)
return 1;
return 0;
}

void out(int x)
{
printf("Game over after %d seconds\n",x);
printf("%d\n",he);
for(int i=1;i<=he;++i)
printf("%d %d %lld %d %d\n",ji[i].age,ji[i].lev,ji[i].blood,ji[i].x,ji[i].y);
}

void outend()
{
printf("The game is going on\n");
printf("%d\n",he);
for(int i=1;i<=he;++i)
printf("%d %d %lld %d %d\n",ji[i].age,ji[i].lev,ji[i].blood,ji[i].x,ji[i].y);
}

//bool tmpp[N][N];
void get_now()
{
printf("\n");
for(int i=0;i<=n;++i)
{
for(int j=0;j<=m;++j)
printf("%d ",ban[i][j]);
printf("\n");
}
printf("\n");
for(int i=1;i<=he;++i)
printf("i=%d if=%d lasx=%d lasy=%d x=%d y=%d age=%d lev=%d blood=%lld\n",i,ji[i].cakeif,ji[i].lasx,ji[i].lasy,ji[i].x,ji[i].y,ji[i].age,ji[i].lev,ji[i].blood);

/*for(int i=1;i<=he;++i)
printf("blood=%lld\n",ji[i].blood);*/

}

inline void work()
{
cake=1;cnt=0;mem(xin,0);
for(int i=1;i<=T;++i)
{
//printf("-----------now=%d\n",i);

if(he<6&&!ban[0][0])
{
++cnt;
ji[++he]=Ant(0,0,0,callev(cnt),calblood(cnt),0);
//printf("lev=%d blood=%lld cnt=%d\n",ji[he].lev,ji[he].blood,cnt);
//printf("cnt=%d\n",cnt);
//ji[he].out();
ban[0][0]=1;
}//get_now();
leftxin();
for(int j=1;j<=he;++j)
move(j);
/*printf("------xinxi------\n");
for(int l=0;l<=n;++l)
{
for(int j=0;j<=m;++j)
printf("%d ",xin[l][j]);
printf("\n");
}
printf("\n");*/
//get_now();
for(int j=1;j<=s;++j)
attack(j);
checkdie();
if(check())
{
out(i);
return ;
}
reducexin();

//get_now();

//for(int i=1;i<=he;++i)
//    ji[i].out();
//printf("he=%d\n",he);

}
outend();
}
int main(){

//freopen("antbuster_ex.in","r",stdin);
//freopen("antbuster_ex.out","w",stdout);

//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);

Init();
work();
}

posted @ 2017-10-10 17:05  A_LEAF  阅读(129)  评论(0编辑  收藏  举报