【bzoj1033】杀蚂蚁

来源:互联网 发布:unity3d 卡通场景下载 编辑:程序博客网 时间:2024/04/30 02:54

似乎是最后一篇了。。。。。感觉大部分类型的题都弄了?(雾)。。。

模拟题镇楼!!!

好吧在判穿透的时候看了hzwer神的题解= =

http://hzwer.com/2738.html

向量法太神了!

const  runx:array[1..4]of longint=(1,0,-1,0);  runy:array[1..4]of longint=(0,1,0,-1);  bilibili=0.5;type  nodeant=record  HP,x,y,canmax,age,lv:longint;  target:boolean;  end;  turretnode=record  x,y:longint;  end;  nodepre=record  x,y:longint  end;  nodepoint=record  x,y:longint;  end;var  i,j,k,n,m,l,r,mid,plus:longint;  ant:array[0..10]of nodeant;  turretnum,antnum,tot,losetime:longint;  maP:array[0..10,0..10]of longint;  cant:array[0..10,0..10]of boolean;  turret:array[0..23]of turretnode;  attdown:array[0..23]of boolean;  pre:array[0..10]of nodepre;  time,endtime:longint;  attackdamage,attackdist:longint;  lostcake,lose:boolean;function qpow(x:extended;y:longint):extended;var i,j:longint;a,b:extended;begin  b:=1.0;  while y<>0 do  begin    if y and 1=1 then b:=b*x;    y:=y shr 1;    if y>0 then x:=x*x  end;  exit(b)end;procedure addage;var i:longint;begin  for i:=1 to antnum do inc(ant[i].age)end;procedure breed;var i,j,k:longint;begin  if (antnum>=6)or(cant[0,0])then exit;  inc(antnum);  inc(tot);  ant[antnum].lv:=(tot+5)div 6;  ant[antnum].hp:=trunc(qpow(1.1,ant[antnum].lv)*4);  ant[antnum].canmax:=ant[antnum].hp;  ant[antnum].x:=0;  ant[antnum].y:=0;  ant[antnum].age:=1;  ant[antnum].target:=false;  cant[ant[antnum].x,ant[antnum].y]:=true;  pre[antnum].x:=0;  pre[antnum].y:=0;end;procedure Pheromones;var i,j,k:longint;begin  for i:=1 to antnum do  if ant[i].HP>=0 then  if not ant[i].target then inc(map[ant[i].x,ant[i].y],2)  else inc(map[ant[i].x,ant[i].y],5)end;procedure spec_move(i,toward:longint);var j,k,nowx,nowy,fangxiang:longint;begin//  if time=15 then writeln('!!!',i,' ',toward);  if toward=233 then begin pre[i].x:=ant[i].x;pre[i].y:=ant[i].y;exit;  end;  fangxiang:=toward;  while 23333=23333 do  begin    fangxiang:=(fangxiang+2)mod 4+1;    nowx:=ant[i].x+runx[fangxiang];    nowy:=ant[i].y+runy[fangxiang];//if time=15 then    writeln(' ',nowx,' ',nowy,'//',fangxiang,'&&',pre[i].x,' ',pre[i].y);    if (nowx<0)or(nowy<0)or(nowx>n)or(nowy>m)or(cant[nowx,nowy])or((nowy=pre[i].y)and(nowx=pre[i].x))then continue;    cant[ant[i].x,ant[i].y]:=false;    pre[i].x:=ant[i].x;pre[i].y:=ant[i].y;    ant[i].x:=nowx;    ant[i].y:=nowy;    cant[ant[i].x,ant[i].y]:=true;    exit  end;end;procedure antmove;var i,j,k:longint;toward,max,tox,toy,nowx,nowy,cannum1,maxnum:longint;begin//  if cant[8,6]then begin writeln('/////',time);halt end;  for i:=1 to antnum do  begin    max:=-maxlongint;    toward:=233;    for j:=1 to 4 do    begin      nowx:=ant[i].x+runx[j];      nowy:=ant[i].y+runy[j];      if (nowx<0)or(nowy<0)or(nowx>n)or(nowy>m)or(cant[nowx,nowy])or((nowy=pre[i].y)and(nowx=pre[i].x))then continue;      if map[nowx,nowy]>max then max:=map[nowx,nowy]    end;    for j:=1 to 4 do    begin      nowx:=ant[i].x+runx[j];      nowy:=ant[i].y+runy[j];      if (nowx<0)or(nowy<0)or(nowx>n)or(nowy>m)or(cant[nowx,nowy])or((nowy=pre[i].y)and(nowx=pre[i].x))then continue;      if map[nowx,nowy]=max then begin toward:=j; break end;    end;    if (ant[i].age mod 5=0)or(toward=233)then spec_move(i,toward)    else    begin      cant[ant[i].x,ant[i].y]:=false;      pre[i].x:=ant[i].x;pre[i].y:=ant[i].y;      ant[i].x:=ant[i].x+runx[toward];      ant[i].y:=ant[i].y+runy[toward];//      if time=18 then//      if i=6 then writeln(ant[i].x,' ',ant[i].y,' ',toward,' ',map[ant[i].x,ant[i].y],' ',map[1,0],' ',cant[0,1],' ',cant[1,0],' ',pre[i].x,' ',pre[i].y);//      if time=15 then writeln(ant[i].x,'^^^^',ant[i].y);//      if time=17 then //     if i=3 then writeln('!!!!!',toward,' ',map[ant[i].x,ant[i].y],' ',map[8,6],' ',cant[8,6]);      cant[ant[i].x,ant[i].y]:=true    end;  end;end;procedure getcake;var i,j,k:longint;begin  lostcake:=false;  for i:=1 to antnum do  if ant[i].target then begin lostcake:=true;exit;end;  for i:=1 to antnum do  if (ant[i].x=n)and(ant[i].y=m)then  begin    if ant[i].target=false then    ant[i].hp:=ant[i].hp+trunc(ant[i].canmax/2);    ant[i].target:=true;    if ant[i].hp>ant[i].canmax then ant[i].hp:=ant[i].canmax;    lostcake:=true;  endend;function dist(a,b,c,d:longint):double;begin  exit(sqrt(sqr(a-c)+sqr(b-d)))end;function min(a,b:longint):longint;begin  if a<b then exit(a);  exit(b)end;function max(a,b:longint):longint;begin  if a>b then exit(a);  exit(b)end;function cmul(a,b:nodepoint):longint;begin  exit(a.x*b.y-a.y*b.x)end;function sub(a,b:nodepoint):nodepoint;var t:nodepoint;begin  t.x:=a.x-b.x;  t.y:=a.y-b.y;  exit(t)end;function turn(a,b,c:nodepoint):longint;begin  exit(cmul(sub(b,a),sub(c,a)))end;procedure special_attack(tnum,anum:longint);var i,j,k:longint;a,b:longint;ax,ay,bx,by:longint;function nengdadao(tnum,anum,k:longint):boolean;var x,y,x1,y1,x2,y2:longint;  dis:double; p,a,b:nodepoint;begin  {if ((x=bx)and(y=by))then exit(true);  if (x<min(ax,bx))or(y<min(ay,by))or(x>max(ax,bx))or(y>max(ay,by))then exit(false);  kk:=(ay-by)/(ax-bx);  b:=ay-kk*ax;  if time>235 then writeln('//',abs(kk*x+b-y):0:2);  if time>235 then    writeln('//',ax,' ',ay,'-->',bx,' ',by,':',ant[i].x,' ',ant[i].y);  if abs(kk*x+b-y)<=bilibili then exit(true);  exit(false)     }   x:=ant[k].x;y:=ant[k].y;  dis:=dist(ax,ay,bx,by);  if ((x=bx)and(y=by))then exit(true);  x1:=min(ax,bx);  y1:=min(ay,by);  x2:=max(ax,bx);  y2:=max(ay,by);  if (x<x1)or(x2<x)or(y1>y)or(y2<y)then exit(false);  p.x:=x;p.y:=y;  a.x:=ax;b.x:=bx;a.y:=ay;b.y:=by;  if abs(turn(a,b,p))/dis<=bilibili then exit(true);  exit(false)end;begin  a:=abs(turret[tnum].x-ant[anum].x);  b:=abs(turret[tnum].y-ant[anum].y);  ax:=turret[tnum].x;ay:=turret[tnum].y;  bx:=ant[anum].x;by:=ant[anum].y;//  if (ax<>bx)and(ay<>by)then  for i:=1 to antnum do  if nengdadao(tnum,anum,i)then  begin    dec(ant[i].hp,attackdamage);//    if time>235 then//    writeln(ax,' ',ay,'-->',bx,' ',by,':',ant[i].x,' ',ant[i].y)  end{  else  else  begin    if ax=bx then    begin      for i:=1 to antnum do      if (ant[i].x=ax)and((ay-ant[i].y)*(by-ant[i].y)<=0)then      begin        dec(ant[i].hp,attackdamage); //   if time>235 then //       writeln(ax,' ',ay,'--->',bx,' ',by,':',ant[i].x,' ',ant[i].y)      end;    end;    if ay=by then    begin      for i:=1 to antnum do      if (ant[i].y=ay)and((ax-ant[i].x)*(bx-ant[i].x)<=0)then      begin        dec(ant[i].hp,attackdamage);//    if time>235 then //       writeln(ax,' ',ay,'---->',bx,' ',by,':',ant[i].x,' ',ant[i].y)      end;    end;   end;     }//  if time>235 then//  writeln;end;procedure assault;var i,j,k:longint;targetnum:longint;min:double;minnum:longint;begin  fillchar(attdown,sizeof(attdown),false);  if lostcake then  begin    for i:=1 to antnum do    if ant[i].target then targetnum:=i;    for i:=1 to turretnum do    if dist(turret[i].x,turret[i].y,ant[targetnum].x,ant[targetnum].y)<=attackdist then    begin      attdown[i]:=true;//      dec(ant[targetnum].hp,attackdamage);      special_attack(i,targetnum);    end;    if ant[targetnum].hp<0 then begin lostcake:=false;end    else if (ant[targetnum].x=0)and(ant[targetnum].y=0)then begin lose:=true;losetime:=time;end;  end;  for i:=1 to turretnum do  if attdown[i]=false then  begin    minnum:=233;    min:=maxlongint;    for j:=1 to antnum do    if dist(turret[i].x,turret[i].y,ant[j].x,ant[j].y)<=attackdist then    if dist(turret[i].x,turret[i].y,ant[j].x,ant[j].y)<min then    begin      min:=dist(turret[i].x,turret[i].y,ant[j].x,ant[j].y);      minnum:=j    end;    if minnum=233 then continue;    attdown[i]:=true;  //  dec(ant[minnum].hp,attackdamage);    special_attack(i,minnum);  endend;procedure burial;var i,j,k,tot:longint;begin  tot:=0;  for i:=1 to antnum do  if ant[i].hp>=0 then  begin    inc(tot);    ant[tot]:=ant[i];    pre[tot]:=pre[i];  end  else cant[ant[i].x,ant[i].y]:=false;  antnum:=totend;procedure spec_Pheromones;var i,j:longint;begin  for i:=0 to m do  for j:=0 to n do  if map[j,i]>0 then dec(map[j,i])end;begin  readln(m,n);  readln(turretnum,attackdamage,attackdist);  for i:=1 to turretnum do  begin    readln(turret[i].y,turret[i].x);    cant[turret[i].x,turret[i].y]:=true  end;  readln(endtime);  for time:=1 to endtime do  begin    addage;    breed;    Pheromones;    antmove;    getcake;    assault;    burial;    spec_pheromones;    if lose=true then break;//    if time>235 then//    begin//    writeln('//',time);//    for i:=1 to antnum do writeln(ant[i].age,' ',ant[i].lv,' ',ant[i].hp,' ',ant[i].y,' ',ant[i].x);//    end;    {if time=58 then    begin      for i:=0 to m do      begin        for j:=0 to n do write(map[i,j]);        writeln      end;    end;      }{    if time>235 then    for i:=0 to m do    begin      for j:=0 to n do write(map[j,i],' ');      writeln    end;   }  end;  if lose then plus:=-1 else plus:=0;  if lose then writeln('Game over after ',losetime,' seconds')  else writeln('The game is going on');  writeln(antnum);  for i:=1 to antnum do writeln(ant[i].age+plus,' ',ant[i].lv,' ',ant[i].hp,' ',ant[i].y,' ',ant[i].x) end.


0 0