poj 1077 eight
分析:经典的八数码问题,这里用的是heap+A*。
A*很明显是用那个经典的A*,heap的维护和k短路非常像。
第二个简单A*
代码(模仿某人的):
const nx:array[1..9] of integer=(1,1,1,2,2,2,3,3,3); ny:array[1..9] of integer=(1,2,3,1,2,3,1,2,3); ji:array[0..9] of longint=(1,1,2,6,24,120,720,5040,40320,362880); type arr=array[1..9] of integer; var q:array[0..10000] of integer; f:array[0..10000] of arr; d:array[0..10000] of string; v:array[0..730000] of boolean; p,i,j,k,st,pp:longint; a:arr; ch:char; procedure swap(var x,y:integer); begin x:=x xor y; y:=x xor y; x:=x xor y; end; procedure swaa(var x,y:arr); var k:arr; begin k:=x; x:=y; y:=k; end; procedure swas(var x,y:string); var k:string; begin k:=x; x:=y; y:=k; end; procedure ok; var k:longint; begin k:=0; for i:=2 to 9 do if a[i]<>0 then for j:=1 to i-1 do if a[j]>a[i] then inc(k); if odd(k) then begin writeln('unsolvable'); halt; end; end; function hash:longint; var i,j,k:longint; begin hash:=0; for i:=1 to 8 do if f[p,i]<>0 then begin k:=0; for j:=i+1 to 9 do if (f[p,j]<f[p,i])and(f[p,j]<>0) then inc(k); hash:=hash+ji[9-i]*k; end; for i:=1 to 9 do if f[p,i]=0 then hash:=hash+ji[9-i]*(9-i); hash:=hash+1; end; procedure up; var fa,son:longint; begin son:=p; fa:=p>>1; while fa>1 do begin if q[son]<q[fa] then begin swap(q[son],q[fa]); swas(d[son],d[fa]); swaa(f[son],f[fa]); end else exit; son:=fa; fa:=son>>1; end; end; procedure down; var fa,son:longint; begin fa:=1; son:=2; while son<=p do begin if (son<p)and(q[son+1]<q[son]) then inc(son); if q[son]<q[fa] then begin swap(q[son],q[fa]); swas(d[son],d[fa]); swaa(f[son],f[fa]); end else exit; fa:=son; son:=fa*2; end; end; procedure find(l,r:longint; ch:char); var i:longint; begin inc(p); f[p]:=f[1]; swap(f[p,l],f[p,r]); i:=hash; if v[i] then begin dec(p); exit; end else v[i]:=true; d[p]:=d[1]+ch; q[p]:=0; for i:=1 to 9 do if f[p,i]<>0 then inc(q[p],abs(nx[i]-nx[f[p,i]])+abs(ny[i]-ny[f[p,i]])); up; end; begin for i:=1 to 3 do for j:=1 to 3 do begin repeat read(ch); until ch<>' '; inc(k); if ch='x' then continue; a[k]:=ord(ch)-48; inc(st,abs(i-nx[a[k]])); inc(st,abs(j-ny[a[k]])); end; ok; p:=1; q[1]:=st; f[1]:=a; v[hash]:=true; while p>0 do begin if q[1]=0 then begin writeln(d[1]); halt; end; for i:=1 to 9 do if f[1,i]=0 then begin k:=i; break; end; if k-3>0 then find(k,k-3,'u'); if k+3<9 then find(k,k+3,'d'); if (k mod 3<>1)and(k>1) then find(k,k-1,'l'); if (k mod 3<>0)and(k<9) then find(k,k+1,'r'); q[1]:=q[p]; d[1]:=d[p]; f[1]:=f[p]; q[p]:=0; d[p]:=''; dec(p); down; end; end.