特长生模拟——八数码问题
来源:互联网 发布:淘宝产品摄影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.
阅读全文
1 0
- 特长生模拟——八数码问题
- 特长生模拟 八数码(bfs+hash)
- 特长生模拟——楼层
- 特长生模拟——朋友
- 特长生模拟——门票
- 特长生模拟——侦察兵
- 特长生模拟——遭遇战
- 特长生模拟——Array
- 特长生模拟——Biotech
- 特长生模拟——采药
- 特长生模拟——立体图
- 八数码问题——A*搜索
- 八数码问题——HDU 1043
- 双向BFS——八数码问题
- 八数码——路径寻找问题
- MATLAB—A*解决八数码问题
- 特长生模拟——买装备
- 特长生模拟——DNA排序
- Mybatis Plugin 破解
- android Service的用法
- 网站优化的3个seo小技巧
- llinux系统查询端口是否被占用
- [Hackerrank题目选做] Sorted Subsegments 二分+线段树
- 特长生模拟——八数码问题
- PCA 主成分分析Principal components analysis
- SDK安装的闪退问题
- 最新盘点当今10个顶尖的机床系统及厂家
- CTF 题目练习题库
- 哲学家就餐问题实现
- ubuntu 16.04 下配置intel/caffe
- [bzoj4931][SDOI省队集训2017]塔
- Python学习 Python3.5+PyQt5环境--------01、从一个GUI开始