特长生模拟——八数码问题

来源:互联网 发布:淘宝产品摄影moxin020 编辑:程序博客网 时间:2024/06/05 08:16

题目大意:
这里写图片描述
这里写图片描述

题解:
广搜+hash:
这题可以用广搜做,怎么做呢?
首先每次找0的位置然后向四边拓展,我们观察可以发现,这题所有的组合有9!个,这时候广搜会有特别多的重复,我们就采用hash判重,把每一次搜索到的数插入到hash表中,然后每一次搜索时,查询当前的状态是否存在hash表中。
hash表因为不可能开到876543210,这时候我们发现因为他只有9!种状态,我们就用一个大于9!的质数去mod,然后再存入hash表中。

const     dx:array [1..4] of longint=(1,0,0,-1);     dy:array [1..4] of longint=(0,1,-1,0);     modn=400007;var     a:Array [0..400001,1..3,1..3] of longint;     c:Array [0..400001] of longint;     hash:array [0..modn,1..3,1..3] of longint;     i,j:longint;function pan(aa,bb:longint):boolean;begin     if (aa<1) or (aa>3) or (bb<1) or (bb>3) then exit(false);     exit(true);end;function check(t,tt:longint):boolean;var     i,j,k,l:longint;begin     k:=0; l:=0;     for i:=1 to 3 do        for j:=1 to 3 do        begin            if hash[t,i,j]=a[tt,i,j] then inc(k);            if hash[t,i,j]=0 then inc(l);        end;     if (k=9) or (l=9) then exit(false);     exit(true);end;function lowbit(t:longint):longint;var     i,j,k:longint;begin     k:=0;     for i:=1 to 3 do         for j:=1 to 3 do             k:=k*10+a[t,i,j];     k:=k mod modn;     while check(k,t) do     begin         inc(k);         if k>modn then k:=1;     end;     exit(k);end;function find(kd:longint):boolean;var    i,j,k,l:longint;begin    k:=lowbit(kd);    l:=0;    for i:=1 to 3 do        for j:=1 to 3 do        if hash[k,i,j]<>a[kd,i,j] then exit(false);    exit(true);end;procedure bfs;var     head,tail,i,j,k,l,x,y,x1,y1,p,q:longint;begin     head:=0;     tail:=1;     c[1]:=0;     hash[lowbit(1)]:=a[1];     while head<tail do     begin           inc(head);           k:=0;           for i:=1 to 3 do               for j:=1 to 3 do               begin                   if a[head,i,j]=0 then                   begin                        x:=i;                        y:=j;                   end;                   if a[head,i,j]=a[0,i,j] then inc(k);               end;           if k=9 then begin                             writeln(c[head]);                             halt;                       end;           for i:=1 to 4 do           begin                x1:=x; y1:=y; k:=0;                while pan(x1+dx[i],y1+dy[i]) do                begin                      inc(k);                      inc(tail);                      a[tail]:=a[head];                      c[tail]:=c[head]+k;                      p:=x; q:=y;                      for j:=1 to k do                      begin                           l:=a[tail,p,q];                           a[tail,p,q]:=a[tail,p+dx[i],q+dy[i]];                           a[tail,p+dx[i],q+dy[i]]:=l;                      end;                      if find(tail) then begin dec(tail); break end                                    else hash[lowbit(tail)]:=a[tail];                end;           end;     end;     writeln('-1');end;begin     assign(input,'eight.in'); reset(input);     assign(output,'eight.out'); rewrite(output);     for i:=1 to 3 do     begin         for j:=1 to 3 do read(a[1,i,j]);         readln;     end;     for i:=1 to 3 do     begin         for j:=1 to 3 do read(a[0,i,j]);         readln;     end;     bfs;     close(input); close(output);end.
原创粉丝点击