[bzoj1033]杀蚂蚁
这只是一道模拟题而已啊(大雾)
但是需要掌握一些简单的解析几何知识
个人觉得写结构体没什么必要啊,直接写过程就行了
主要是根据题目最后给出的顺序来做,有一下坑点:
1.只能存存在的蚂蚁,否则会tle(高攻击塔)
2.出生时间是年龄+1
3.game over了年龄不用+1
4.血量是先乘上4再取整
5.(0,0)有蚂蚁不生成
6.蚂蚁是一个半径0.5的圆
7.出生时间是5的倍数选择只考虑能否走
8.按蚂蚁出生顺序来移动
9.信息素只有大于0时才会-1
10.激光不会穿透
11.死亡要从后往前算
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 25 4 #define sqr(x) ((x)*(x)) 5 struct ji{ 6 int x,y; 7 bool operator ==(const ji &a)const{ 8 return (x==a.x)&&(y==a.y); 9 } 10 bool operator !=(const ji &a)const{ 11 return (x!=a.x)||(y!=a.y); 12 } 13 }ta[N],wei[N],pre[N]; 14 int n,m,s,d,r,t,dx[4]={-1,0,1,0},dy[4]={0,-1,0,1}; 15 int tar,sz,dj[N],blo[N],old[N],in[N][N]; 16 int blood(int k){ 17 return floor(4*pow(1.1,(k+5)/6)); 18 } 19 int dis(ji x,ji y){ 20 return sqr(x.x-y.x)+sqr(x.y-y.y); 21 } 22 int find(ji k){ 23 return in[k.x][k.y]; 24 } 25 void born(){ 26 old[++sz]=0; 27 dj[sz]=++dj[0]; 28 blo[sz]=blood(dj[sz]); 29 pre[sz]=wei[sz]=ji{0,0}; 30 } 31 void del(int k){ 32 if (tar==k)tar=0; 33 if (tar>k)tar--; 34 for(int i=k;i<sz;i++){ 35 dj[i]=dj[i+1]; 36 old[i]=old[i+1]; 37 blo[i]=blo[i+1]; 38 wei[i]=wei[i+1]; 39 pre[i]=pre[i+1]; 40 } 41 sz--; 42 } 43 ji move(ji k,int x){ 44 return ji{k.x+dx[x],k.y+dy[x]}; 45 } 46 bool pd(ji k){ 47 if ((k.x<0)||(k.y<0)||(k.x>n)||(k.y>m))return 0; 48 for(int i=1;i<=sz;i++) 49 if (k==wei[i])return 0; 50 for(int i=1;i<=s;i++) 51 if (k==ta[i])return 0; 52 return 1; 53 } 54 double f(double x,double a,double b,double c){ 55 return a*x*x+b*x+c; 56 } 57 bool jiao(ji x,ji y,ji z){ 58 if (x.x==y.x)return (x.x==z.x)&&((z.y-x.y)*(z.y-y.y)<=0); 59 if (x.x>y.x)swap(x,y); 60 double k=1.0*(y.y-x.y)/(y.x-x.x),b2=1.0*x.y-k*x.x; 61 double a=k*k+1.0,b=2*(b2*k-z.y*k-z.x),c=sqr(b2-z.y)+sqr(z.x); 62 if ((f(x.x,a,b,c)<=0.25)||(f(y.x,a,b,c)<=0.25))return 1; 63 double dui=-0.5*b/a; 64 return (x.x<=dui)&&(dui<=y.x)&&(f(dui,a,b,c)<=0.25); 65 } 66 int main(){ 67 scanf("%d%d%d%d%d",&n,&m,&s,&d,&r); 68 r*=r; 69 for(int i=1;i<=s;i++)scanf("%d%d",&ta[i].x,&ta[i].y); 70 scanf("%d",&t); 71 for(int ii=1;ii<=t;ii++){ 72 if ((sz<6)&&(pd(ji{0,0})))born(); 73 for(int i=1;i<=sz;i++)in[wei[i].x][wei[i].y]+=2+(i==tar)*3; 74 for(int i=1;i<=sz;i++){ 75 int fx=-1,ma=-1; 76 for(int j=0;j<4;j++){ 77 ji k=move(wei[i],j); 78 if ((k!=pre[i])&&(pd(k))&&(find(k)>=ma)){ 79 fx=j; 80 ma=find(k); 81 } 82 } 83 if (fx==-1){ 84 pre[i]=wei[i]; 85 continue; 86 } 87 if (old[i]%5==4) 88 while (1){ 89 ji k=move(wei[i],fx=(fx+1)%4); 90 if ((k!=pre[i])&&(pd(k)))break; 91 } 92 pre[i]=wei[i]; 93 wei[i]=move(wei[i],fx); 94 } 95 if (!tar) 96 for(int i=1;i<=sz;i++) 97 if (wei[i]==ji{n,m}){ 98 tar=i; 99 blo[i]=min(blood(dj[i]),blo[i]+blood(dj[i])/2); 100 } 101 for(int i=1;i<=s;i++){ 102 int mb=0,mi=0x3f3f3f3f; 103 if ((tar)&&(dis(ta[i],wei[tar])<=r))mb=tar; 104 else{ 105 for(int j=1;j<=sz;j++)mi=min(mi,dis(ta[i],wei[j])); 106 if (mi>r)continue; 107 for(int j=1;j<=sz;j++) 108 if (dis(ta[i],wei[j])==mi){ 109 mb=j; 110 break; 111 } 112 } 113 for(int j=1;j<=sz;j++) 114 if (jiao(wei[mb],ta[i],wei[j]))blo[j]-=d; 115 } 116 for(int i=sz;i;i--) 117 if (blo[i]<0)del(i); 118 if ((tar)&&(wei[tar]==ji{0,0})){ 119 printf("Game over after %d seconds\n",ii); 120 break; 121 } 122 for(int i=0;i<=n;i++) 123 for(int j=0;j<=m;j++) 124 if (in[i][j])in[i][j]--; 125 for(int i=1;i<=sz;i++)old[i]++; 126 if (ii==t)printf("The game is going on\n"); 127 } 128 printf("%d\n",sz); 129 for(int i=1;i<=sz;i++) 130 printf("%d %d %d %d %d\n",old[i],(dj[i]+5)/6,blo[i],wei[i].x,wei[i].y); 131 }