简单模拟题

答案是0  也就是追不到的条件是 陷入死循环

   

     怎么陷入死循环  就是进入了一个以前进入过的状态

记六维数组hash[fx,fy,cx,cy,fdir,cdir]表示当farmer农民在(fx,fy) 奶牛在(cx,cy) 农民此时方向为fdir 奶牛为cdir

                                                 是否出现过

等于是hash表吧

当然网上还有几种做法

1、

状态只有(10*10*4)400种,两个人最多(400*400)160000种,也就是说,如果超过160000步,那么肯定会出现有的状态出现了2次以上,那么就肯定是一个死循环,永远不会相遇。

判断无解也可以通过判断当前状态是否出现过——使用源码中until的前两个条件即可。


其实160000种状态可以用一个6维bool数组存起来,不会超。当状态重复出现就是不可能相遇了。 直接模拟。

2、

优化

利用运动周期 大大降低循环次数(code已给出)

易证明:奶牛及约翰各自最终运动路线为一循环.

故:只需模拟时间为二者运动周期最小公倍数之前的所有状态即可.

开数组(以奶牛为例) cow[cowx,cowy,cowface]记录奶牛第一次到达格子[x,y]及朝向状态的时间

当奶牛第二次处于此状态时 显然 奶牛运动周期为cyclecow=time(当前时间)-cow[cowx,cowy,cowface]

nocow上有解释 

具体见代码

{
ID: xiaweiy1
PROG: ttwo
LANG: PASCAL
}
const dx:array[1..4]of longint=(-1 , 0, 1 , 0);
dy:array[
1..4]of longint=(0 , 1, 0 , -1);
var i,j,tme,fdir,cdir,fx,fy,tx,ty,cx,cy,px,py:longint;
pd:boolean;
map:array[
1..10,1..10]of char;
hash:array[
1..10,1..10,1..10,1..10,1..4,1..4]of longint;
begin
assign(input,
'ttwo.in');
reset(input);
assign(output,
'ttwo.out');
rewrite(output);
for i:=1 to 10 do
begin
for j:=1 to 10 do
begin
read(map[i,j]);
if map[i,j]='F' then
begin
fx:
=i; fy:=j;
end
else if map[i,j]='C' then
begin
cx:
=i; cy:=j;
end;
end;
readln;
end;
hash[fx,fy,cx,cy,
1,1]:=1;
tme:
=1; //nowtime;
pd:=true;
fdir:
=1; cdir:=1;
while pd do
begin
tx:
=fx+dx[fdir]; ty:=fy+dy[fdir];
if (tx<=0)or(tx>10)or(ty<=0)or(ty>10)or(map[tx,ty]='*') then
begin
tx:
=fx; ty:=fy;
fdir:
=fdir+1; if fdir=5 then fdir:=1; //1:up 2:right 3:down 4:left
end;
px:
=cx+dx[cdir]; py:=cy+dy[cdir];
if (px<=0)or(px>10)or(py<=0)or(py>10)or(map[px,py]='*') then
begin
px:
=cx; py:=cy;
cdir:
=cdir+1; if cdir=5 then cdir:=1; //1:up 2:right 3:down 4:left
end;
if hash[tx,ty,px,py,fdir,cdir]=0 then
begin
if (tx=px)and(ty=py) then break;
inc(tme);
hash[tx,ty,px,py,fdir,cdir]:
=1;
end
else pd:=false;
fx:
=tx; fy:=ty; cx:=px; cy:=py;
end;
if not pd then
writeln(
0)
else
writeln(tme);
close(input);
close(output);
end.
posted on 2011-02-12 17:56  Dimfouasstrawberry  阅读(226)  评论(0)    收藏  举报