首页 > 代码库 > [ZJOI2008]杀蚂蚁 Solution

[ZJOI2008]杀蚂蚁 Solution

题目太长,不在此显示,见洛谷P2586

http://daniu.luogu.org/problem/show?pid=2586



模拟,

那就模拟呗;

各种WA,

然后好久才A了;

一种被社会报复了的感觉

好像被蚂蚁踩死了

代码能力太差

唉,正题:

整体流程:

1.蚂蚁出生;

2.放信息素;

3.到处乱跑;

4.被弄死;

5.结算;

6.(神允许)时间流动;

然后是一些细节:

1.输出的蚂蚁年龄,把刚出生的蚂蚁视为0岁,直到一次时间流动后才是1岁,然而与移动方向相关的年龄视刚出生的蚂蚁为1岁

2.可以伪链式存储蚂蚁,以方便查询

3.对于一只蚂蚁,如果她要移动,则不能移动回上回合呆的地方(上上回合呆的地方可以)

4.不移动的蚂蚁也有可能变成target----(上回合的target挂了,然后这只蚂蚁被卡在(n,m)点)

5.炮塔选定目标时,把蚂蚁看为点,然而结算一次攻击的波及范围时,把蚂蚁看做圆

6.半径0.5

7.炮塔同时选目标,同时攻击

8.仔细阅读如下文字:“只要目标在其射程内,塔到目标蚂蚁圆心的连线上的所有蚂蚁......”好像是说如果目标不在射程内,谁也不会被攻击

9.其他一些,诸如,信息素别减爆、血量别加超,之类的;

代码如下:(因为没有重构,所以代码十分难看)

#include<cstdio>using namespace std;struct ANT{    int x,y,time,blo,blo_up,lv,lx,ly,next;    bool cake;};struct Tour{    int x,y;};ANT ant[200010];int tot,many,target,top=0;Tour tour[22];int n,m,s,d,r,t;int ma_su[10][10];int ma_th[10][10];int xx[4]={0,1,0,-1};int yy[4]={1,0,-1,0};void Init();void work();void born();double Sqr(int );void put_su();void run();void hurt();bool cmp(int ,int ,int ,int ,int ,int );bool check();void print();int main(){    Init();    work();}void Init(){    int i,j,k;    scanf("%d%d",&n,&m);    scanf("%d%d%d",&s,&d,&r);    for(i=1;i<=s;i++){        scanf("%d%d",&tour[i].x,&tour[i].y);        ma_th[tour[i].x][tour[i].y]=-1;    }    scanf("%d",&t);    tot=many=target=0;    return ;}void work(){    int i,j,T=0;    while(++T<=t){        born();        put_su();        run();        hurt();        if(check()){            printf("Game over after %d seconds\n",T);            print();            return;        }        for(i=0;i<=n;i++)            for(j=0;j<=m;j++)                ma_su[i][j]-=(ma_su[i][j]!=0?1:0);        for(i=1;i<=tot;i++)            ant[i].time++;    }    printf("The game is going on\n");    print();    return;}void born(){    if(!ma_th[0][0]&&many<6){    	ant[top].next=++tot;        ant[tot].lv=(tot-1)/6+1;        ant[tot].blo=ant[tot].blo_up=int(4*Sqr(ant[tot].lv));        ant[tot].time=0;        ant[tot].x=ant[tot].y=0;ant[tot].lx=ant[tot].ly=-1;        ma_th[0][0]=tot;        many++;        top=tot;    }}double Sqr(int m){    double ans=1,x=1.1;    while(m){        if(m&1)            ans*=x;        m>>=1;        x*=x;    }    return ans;}void put_su(){    int i;    for(i=1;i<=tot;i++)        if(ant[i].blo>=0)            ma_su[ant[i].x][ant[i].y]+=(ant[i].cake?5:2);}void run(){    int i,j,k,fx,X,Y,max;    for(i=ant[0].next;i;i=ant[i].next){        fx=-1;max=-1;        for(j=0;j<=3;j++){            X=ant[i].x+xx[j];            Y=ant[i].y+yy[j];            if(X<=n&&X>=0&&Y<=m&&Y>=0&&(X!=ant[i].lx||Y!=ant[i].ly)&&(!ma_th[X][Y])&&ma_su[X][Y]>max){                max=ma_su[X][Y];                fx=j;            }        }        if(fx!=-1){           	if(!((ant[i].time+1)%5))           		for(j=1;j<=4;j++){           	        fx=(fx+4-1)%4;           	        X=ant[i].x+xx[fx];            	    Y=ant[i].y+yy[fx];           		    if(X<=n&&X>=0&&Y<=m&&Y>=0&&(X!=ant[i].lx||Y!=ant[i].ly)&&(!ma_th[X][Y]))           	            break;           	    }           	ma_th[ant[i].x][ant[i].y]=0;           	ant[i].lx=ant[i].x;ant[i].ly=ant[i].y;           	ant[i].x+=xx[fx];ant[i].y+=yy[fx];       	}       	else{       		ant[i].lx=-1;           	ant[i].ly=-1;    	}        if(ant[i].x==n&&ant[i].y==m&&!target){            target=i;            ant[i].cake=true;            ant[i].blo=ant[i].blo+ant[i].blo_up/2<ant[i].blo_up?ant[i].blo+ant[i].blo_up/2:ant[i].blo_up;        }        ma_th[ant[i].x][ant[i].y]=i;    }}void hurt(){    int i,j,k,len,targ=-1,X,Y;    for(i=1;i<=s;i++){    	X=ant[target].x-tour[i].x;Y=ant[target].y-tour[i].y;    	if(!target||X*X+Y*Y>r*r){    		len=10010;        	for(j=ant[0].next;j;j=ant[j].next)        		if((tour[i].x-ant[j].x)*(tour[i].x-ant[j].x)+(tour[i].y-ant[j].y)*(tour[i].y-ant[j].y)<len){        	        targ=j;len=(tour[i].x-ant[j].x)*(tour[i].x-ant[j].x)+(tour[i].y-ant[j].y)*(tour[i].y-ant[j].y);        	    }        }		else			targ=target;		X=ant[targ].x-tour[i].x;Y=ant[targ].y-tour[i].y;		if(X*X+Y*Y<=r*r)		for(j=ant[0].next;j;j=ant[j].next)            if(cmp(ant[j].x,ant[j].y,tour[i].x,tour[i].y,ant[targ].x,ant[targ].y))                ant[j].blo-=d;    }    j=0;    for(i=ant[j].next;i;i=ant[i].next)        	if(ant[i].blo<0){        		ma_th[ant[i].x][ant[i].y]=0;many--;        		ant[j].next=ant[i].next;        		if(i==target)        			ant[i].cake=false;        		if(i==top)        			top=j;			}			else				j=i;    if(!ant[target].cake)        target=0;}bool cmp(int ax,int ay,int tx,int ty,int targx,int targy){	double t_ax=ax-tx,t_ay=ay-ty,targ_ax=ax-targx,targ_ay=ay-targy,t_targx=targx-tx,t_targy=targy-ty;	double R=(t_ax*t_targx+t_ay*t_targy)/(t_targx*t_targx+t_targy*t_targy);	if(R<=0)return (t_ax*t_ax+t_ay*t_ay)<=0.25; 	if(R>=1)return (targ_ax*targ_ax+targ_ay*targ_ay)<=0.25;	double px=tx+(targx-tx)*R;	double py=ty+(targy-ty)*R;	return (ax-px)*(ax-px)+(ay-py)*(ay-py)<=0.25;}bool check(){    return (target&&!ant[target].x&&!ant[target].y);}void print(){    int i;    printf("%d\n",many);    for(i=ant[0].next;i;i=ant[i].next)        printf("%d %d %d %d %d\n",ant[i].time,ant[i].lv,ant[i].blo,ant[i].x,ant[i].y);}

祝AC

[ZJOI2008]杀蚂蚁 Solution