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.