Luogu2586 [ZJOI2008]杀蚂蚁
https://www.luogu.com.cn/problem/P2586
模拟
按题意模拟
注意点:
\(1.\)判断激光是否会打到其他蚂蚁的判断要小心(计算几何基础都不扎实),实际上我的的代码中不是很科学,应当算出与直线与圆的交点然后判断,而我直接判断圆心是否夹在线段的两个端点中间,但是在本题中,如果圆心恰好与线段端点在同一水平(或垂直)线上,那么它显然比我们找到的点与塔更近,矛盾
\(2.\)当蚂蚁年龄为\(5\)的倍数时,蚂蚁的转向仍然要满足不回到原来位置
\(3.\)当扛着蛋糕的蚂蚁被杀死后,如果在\((n,m)\)的蚂蚁在下一秒无法运动,那么它将拿到蛋糕
\(4.\)当一只蚂蚁在这一轮无法动时,它的上一次方向要丢弃
\(Code:\)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define N 9
#define check(x,y) (x>=0 && x<=n && y>=0 && y<=m && !a[x][y].kd)
#define K(x,y) a[x][y].kd
#define I(x,y) a[x][y].id
#define im(x,y) a[x][y].xxs
#define lst(x) ant[x].tag
#define old(x) ant[x].od
#define le(x) ant[x].lev
#define bl(x) ant[x].blood
#define fbl(x) ant[x].fblood
#define L(x) ant[x].l
#define R(x) ant[x].r
#define cake(x) ant[x].ck
#define D double
using namespace std;
int n,m,x,y,s,d,c,kr,sqrkr,T,rc,cnt,e[25][2];
int dic[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
bool die[10];
D le_bl=4.0;
bool flag=false;
struct Ant
{
int tag=-8;
int od,lev,blood,fblood,l,r;
bool ck=false;
void set0()
{
tag=-8,od=lev=blood=fblood=l=r=0,ck=false;
}
}ant[10],rant[10];
struct node
{
int kd=0,id,xxs=0;
node (int kk=0,int ii=0)
{
kd=kk,id=ii;
}
}a[N][N];
void New_Ant()
{
if (cnt>=6 || K(0,0)!=0)
return;
rc++,cnt++;
K(0,0)=2;
I(0,0)=cnt;
if ((rc-1)%6==0)
le_bl*=1.1;
ant[cnt].set0();
le(cnt)=(rc-1)/6+1;
fbl(cnt)=bl(cnt)=(int)le_bl;
}
void Left_Information()
{
for (int i=1;i<=cnt;i++)
if (cake(i))
im(L(i),R(i))+=5; else
im(L(i),R(i))+=2;
}
void Get_Cake(int x)
{
if (c)
return;
if (L(x)==n && R(x)==m)
{
cake(x)=true;
bl(x)+=fbl(x) >> 1;
if (bl(x)>fbl(x))
bl(x)=fbl(x);
c=x;
}
}
void Move_One_Ant(int x)
{
int mxx=-1,qr;
for (int i=0;i<4;i++)
if (abs(i-lst(x))!=2)
{
int nl=L(x)+dic[i][0];
int nr=R(x)+dic[i][1];
if (!check(nl,nr))
continue;
if (im(nl,nr)>mxx)
{
mxx=im(nl,nr);
qr=i;
}
}
if (mxx==-1)
{
lst(x)=-8;
Get_Cake(x);
return;
}
if ((old(x)+1)%5==0)
{
int nx=qr-1;
if (nx==-1)
nx=3;
bool t=false;
for (;;)
{
int nl=L(x)+dic[nx][0];
int nr=R(x)+dic[nx][1];
if (check(nl,nr) && abs(nx-lst(x))!=2)
{
qr=nx;
break;
}
nx--;
if (nx==-1)
nx=3;
}
}
lst(x)=qr;
int nl=L(x)+dic[qr][0];
int nr=R(x)+dic[qr][1];
K(L(x),R(x))=0,I(nl,nr)=0;
K(nl,nr)=2,I(nl,nr)=x;
L(x)=nl,R(x)=nr;
Get_Cake(x);
}
void Ant_Move()
{
for (int i=1;i<=cnt;i++)
Move_One_Ant(i);
}
int SqrDis(int x,int y,int c)
{
return (x-L(c))*(x-L(c))+(y-R(c))*(y-R(c));
}
bool Mid(int x,int y,int c,int d)
{
if (x<L(c) && L(c)<L(d))
return true;
if (L(d)<L(c) && L(c)<x)
return true;
if (y<R(c) && R(c)<R(d))
return true;
if (R(d)<R(c) && R(c)<y)
return true;
if (L(c)<x && x<L(d))
return true;
if (L(c)>x && x>L(d))
return true;
if (R(c)<y && y<R(d))
return true;
if (R(c)>y && y>R(d))
return true;
return false;
}
D Dis_Point_To_Line(D x0,D y0,D A,D B,D C)
{
return fabs(((D)A*x0+(D)B*y0+C)/sqrt(A*A+B*B));
}
void Get_Line(D &A,D &B,D &C,D x,D y,D x0,D y0)
{
if (x==x0)
{
A=1,B=0,C=-x;
return;
}
if (y==y0)
{
A=0,B=1,C=-y;
return;
}
D k,b;
k=(y0-y)/(x0-x);
b=y-k*x;
A=-k,B=1,C=-b;
}
bool On_Line(D A,D B,D C,D x,D y)
{
return A*x+B*y+C==0;
}
void Kill(int x,int y,int c)
{
D A,B,C;
Get_Line(A,B,C,x,y,L(c),R(c));
for (int i=1;i<=cnt;i++)
if (Dis_Point_To_Line(L(i),R(i),A,B,C)<=0.5 && !Mid(x,y,c,i))
bl(i)-=d;
}
void Use_Tower(int x,int y)
{
if (c && SqrDis(x,y,c)<=sqrkr)
{
Kill(x,y,c);
return;
}
int mxdis=6662333,kid=0;
for (int i=1;i<=cnt;i++)
if (SqrDis(x,y,i)<=sqrkr && SqrDis(x,y,i)<mxdis)
mxdis=SqrDis(x,y,i),kid=i;
if (!kid)
return;
Kill(x,y,kid);
}
void Tower_Kill()
{
for (int i=1;i<=s;i++)
Use_Tower(e[i][0],e[i][1]);
}
bool Dead(int x)
{
return bl(x)<0;
}
void Deal_With_Dead_Ant()
{
int recnt=0;
for (int i=1;i<=cnt;i++)
if (!Dead(i))
{
rant[++recnt]=ant[i];
if (cake(i))
c=recnt;
} else
{
if (cake(i))
c=0;
K(L(i),R(i))=0;
}
cnt=recnt;
for (int i=1;i<=recnt;i++)
ant[i]=rant[i];
}
void Put_Answer(int TT)
{
if (TT)
printf("Game over after %d seconds\n",TT); else
printf("The game is going on\n");
printf("%d\n",cnt);
for (int i=1;i<=cnt;i++)
printf("%d %d %d %d %d\n",old(i),le(i),bl(i),L(i),R(i));
}
void Lose_Or_Not(int TT)
{
if (c && !L(c) && !R(c))
{
Put_Answer(TT);
exit(0);
}
}
void Modify_Imformation()
{
for (int i=0;i<=n;i++)
for (int j=0;j<=m;j++)
if (im(i,j))
im(i,j)--;
for (int i=1;i<=cnt;i++)
old(i)++;
}
void Type_Ant(int TT=0)
{
putchar('\n');
printf("Ant %d:\n",TT);
for (int i=1;i<=cnt;i++)
printf("%d %d %d %d %d\n",old(i),le(i),bl(i),L(i),R(i));
}
void Type_Im(int TT=0)
{
putchar('\n');
printf("Im %d:\n",TT);
for (int i=0;i<=n;i++)
{
for (int j=0;j<=m;j++)
printf("%d ",im(i,j));
putchar('\n');
}
}
void Type_Map(int TT=0)
{
putchar('\n');
printf("Map %d:\n",TT);
for (int i=0;i<=n;i++)
{
for (int j=0;j<=m;j++)
printf("%d ",K(i,j));
putchar('\n');
}
}
int main()
{
scanf("%d%d",&n,&m);
scanf("%d%d%d",&s,&d,&kr);
sqrkr=kr*kr;
for (int i=1;i<=s;i++)
{
scanf("%d%d",&e[i][0],&e[i][1]);
a[e[i][0]][e[i][1]]=node(1,0);
}
scanf("%d",&T);
for (int TT=1;TT<=T;TT++)
{
New_Ant();
Left_Information();
Ant_Move();
Tower_Kill();
Deal_With_Dead_Ant();
Lose_Or_Not(TT);
Modify_Imformation();
}
Put_Answer(0);
return 0;
}