似乎是最后一篇了。。。。。感觉大部分类型的题都弄了?(雾)。。。
模拟题镇楼!!!
好吧在判穿透的时候看了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.