poj 2688 Cleaning Robot
分析:状态压缩的BFS或者dfs状态+最短路。
前者就是类似于拯救大兵瑞恩的方法,后者非常经典,dfs全排列枚举然后根据最短路相加。
WA三次+TLE一次+AC。
代码:
const
nx:array[1..4] of integer=(0,0,1,-1);
ny:array[1..4] of integer=(1,-1,0,0);
type
ji=record
x,y,s,step:longint;
end;
var
v:array[0..1027,0..24,0..24] of boolean;
q:array[0..1000000] of ji;
b:array[0..25,0..25] of longint;
a:array[0..25,0..25] of char;
sum,head,tail,s,y,x,t,step,now,n,m,i,j,k:longint;
vv:boolean;
begin
readln(m,n);
while m<>0 do
begin
fillchar(v,sizeof(v),0);
sum:=-1;
for i:=1 to n do
begin
for j:=1 to m do
begin
read(a[i,j]);
if a[i,j]='o' then
begin
x:=i;
y:=j;
end else
if a[i,j]='*' then
begin
inc(sum);
b[i,j]:=sum;
end;
end;
readln;
end;
if sum=-1 then
begin
writeln(0);
readln(m,n);
continue;
end;
vv:=false;
head:=1; tail:=1; q[1].x:=x; q[1].y:=y; v[0,x,y]:=true;
while head<=tail do
begin
x:=q[head].x; y:=q[head].y; now:=q[head].s; step:=q[head].step;
for i:=1 to 4 do
begin
s:=x+nx[i]; t:=y+ny[i];
if (s<1)or(t<1)or(s>n)or(t>m) then continue;
if a[s,t]='x' then continue;
if a[s,t]='*' then
begin
if v[now or(1<<b[s,t]),s,t] then continue;
inc(tail);
q[tail].x:=s;
q[tail].y:=t;
q[tail].s:=now or (1<<b[s,t]);
q[tail].step:=step+1;
v[q[tail].s,s,t]:=true;
if q[tail].s=1<<(sum+1)-1 then
begin
writeln(step+1);
vv:=true;
break;
end;
continue;
end;
if v[now,s,t] then continue;
v[now,s,t]:=true;
inc(tail);
q[tail].s:=now;
q[tail].x:=s;
q[tail].y:=t;
q[tail].step:=step+1;
end;
if vv then break;
inc(head);
end;
if not vv then writeln(-1);
readln(m,n);
end;
end.
浙公网安备 33010602011771号