【bzoj1033】杀蚂蚁

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

模拟题镇楼!!!

好吧在判穿透的时候看了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;
  end
end;
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);
  end
end;
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:=tot
end;
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.


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值