6-23 重排n²宫问题


问题描述

重排九宫是一个古老的单人智力游戏。据说重排九宫起源于我国古时由三国演义故事“关羽义释曹操”而设计的智力玩具“华容道”,后来流传到欧洲,将人物变成数字。原始 的重排九宫问题是这样的:将数字 1~8 按照任意次序排在 3×33×33\times3 的方格阵列中,留下一个空格。与空格相邻的数字,允许从上,下,左,右方向移动到空格中。游戏的最终目标是通过 合法移动,将数字 1~8 按行排好序。在一般情况下,重排 n2 宫问题是将数字 1~n2−1n2−1n^2-1 按照 任意次序排在n×nn×n n\times n 的方格阵列中,留下一个空格。允许与空格相邻的数字从上,下,左,右 4 个方向移动到空格中。游戏的最终目标是通过合法移动,将初始状态变换到目标状态。

对于给定的 n×nn×nn\times n 方格阵列中数字 1~n2−1n2−1n^2-1 初始排列和目标状态,编程计算将初始排列通 过合法移动变换为目标状态最少移动次数。

数据输入:
第 1 行有 1 个正整数 n。以下的 n 行是n×nn×nn\times n 方格 阵列的中数字 1~n2−1n2−1n^2-1 的初始排列,每行有 n 个数字表示该行方格中的数字, 0 表示空格。 接着的 n 行是方格阵列中数字 1~n2−1n2−1n^2-1 的目标状态。


Java

package Chapter6FenZhiXianJieFa;import java.util.Collections;
import java.util.Scanner;
import java.util.Vector;public class ChongPaiNxNGong {private static class Board{int y,x;               //空格位置Vector<Integer> path;int dist;              //manhattan距离Vector<Integer> boardm;private int heur(){return dist;}private void getboard(int[] m){for(int i=0; i<boardsz; i++){boardm.add(m[i]);if(m[i] == 0) {y=i/rowsz; x=i%rowsz;}}dist=0;for(int i=0; i<boardsz; i++)if(boardm.get(i) != 0) dist+=getdist(boardm.get(i),i);}//按3个方向移动private boolean move(int dir){final int[][] step = {{0,-1},{0,1},{-1,0},{1,0}};//空格移动方向: 上 下 左 右//dir: 0 1 2 3int nx = x+step[dir][0];int ny = y+step[dir][1];if((path.isEmpty()||op[dir]!=(path.lastElement())) && nx>-1 && nx<rowsz && ny>-1 && ny<rowsz){dist = dist+1-getdist(boardm.get(ny*rowsz+nx),ny*rowsz+nx)+getdist(boardm.get(ny*rowsz+nx),y*rowsz+x);Collections.swap(boardm,y*rowsz+x,ny*rowsz+nx);y=ny; x=nx;path.add(dir);return true;}elsereturn false;}//计算manhattan距离private int getdist(int v, int loc){int dis = Math.abs((pos[v]%rowsz)-(loc%rowsz));dis += Math.abs((pos[v]/rowsz)-(loc/rowsz));return dis;}//到达目标状态private boolean reached(){for(int i=0; i<boardsz; i++)if(boardm.get(i) != dest[i]) return false;return true;}private void out(){char[] dir = {'U','D','L','R'};//空格移动方向: 上 下 左 右//dir: 0 1 2 3System.out.println(path.size());for(int i=0; i<path.size(); i++){System.out.print(dir[path.get(i)]);if(i%20 == 19) System.out.println();}if(path.size()%20 != 0) System.out.println();}}private static final int[] op = {1,0,3,2};private static int maxdep;private static int rowsz,boardsz;private static int[] sour,dest,pos;public static void main(String[] args){Scanner input = new Scanner(System.in);while (true){init(input);if(odd()) idastar();else System.out.println("No Solution!");}}private static void init(Scanner input){rowsz = input.nextInt();boardsz = rowsz*rowsz;sour = new int[boardsz];dest = new int[boardsz];pos = new int[boardsz];for(int i=0; i<boardsz; i++)sour[i] = input.nextInt();for(int i=0; i<boardsz; i++){dest[i] = input.nextInt();pos[dest[i]] = i;}}private static boolean odd(){int[] c = new int[boardsz];int count=0,count1=0,i1=0,j1=0,i2=0,j2=0;for(int k=0; k<boardsz; k++){c[dest[k]] = sour[k];if(sour[k] == 0) {i1=k/rowsz+1; j1=k%rowsz+1;}if(dest[k] == 0) {i2=k/rowsz+1; j2=k%rowsz+1;}}int posi = ((i1+i2)%2+(j1+j2)%2)%2;for(int j=0; j<boardsz; j++){int k=c[j],k1=j;count1 = 0;while (k >= 0) {k=c[k1]; c[k1]=-1; k1=k; count1++;}if(count1 > 0) count+=count1-2;}if(count%2 == posi) return true;else return false;}private static boolean solve(int dep, Board E){if(dep+E.dist <= maxdep){if(E.reached()) {E.out(); return true;}for(int i=0; i<4; i++){
//                Board N = E;Board N = new Board();N.x = E.x;N.y = E.y;N.dist = E.dist;N.boardm = new Vector<>();N.path = new Vector<>();N.boardm = (Vector)E.boardm.clone();N.path = (Vector)E.path.clone();if(N.move(i))if(solve(dep+1,N))return true;}}return false;}//IDA*算法private static void idastar(){Board E = new Board();E.boardm = new Vector<>();E.path = new Vector<>();E.getboard(sour);maxdep = E.heur();if(maxdep == 0){System.out.println(0);return;}while (!solve(0,E))maxdep += 2;}
}

Input & Output

3
1 2 3
4 0 6
7 5 8
1 2 3
4 5 6
7 8 0
2
DR3
1 2 3
4 0 6
7 5 8
1 2 3
4 5 6
7 8 0
2
DR3
6 7 3
2 5 1
8 4 0
1 2 3
4 5 6
7 8 0
26
ULULDRURDDLURDLLURRU
LLDRRD3
7 2 8
5 4 3
6 0 1
1 2 3
4 5 6
7 8 0
No Solution!3
7 0 3
8 1 2
6 5 4
1 2 3
4 5 6
7 8 0
17
DRDLLUURDRDLLURRD

Reference

王晓东《计算机算法设计与分析》

算法设计与分析: 6-23 重排n²宫问题相关推荐

  1. 太原理工大学linux与python编程r实验报告_太原理工大学算法设计与分析实验报告...

    <太原理工大学算法设计与分析实验报告>由会员分享,可在线阅读,更多相关<太原理工大学算法设计与分析实验报告(12页珍藏版)>请在人人文库网上搜索. 1.本科实验报告课程名称: ...

  2. 【算法设计与分析】16 分治策略:快速排序(快速排序的时间复杂度计算)

    上一篇文章学习了:[算法设计与分析]15 分治策略:芯片测试 文章目录 1. 快速排序的基本思想 1.2 时间复杂度的计算 1.21 最坏情况时间复杂度计算 1.22 最好情况时间复杂度 1.23 平 ...

  3. 【算法设计与分析】经典常考三十三道例题AC代码

    ❥小虾目前大三,我校在大一下开设<数据结构>这门课,大二上开了<算法设计与分析>这门课,很庆幸这两门课的上机考试总成绩一门100,一门99,最后总分也都90+.下文会给出机试的 ...

  4. 循环赛日程表非递归Java_王晓东《算法设计与分析》课件.ppt

    <王晓东<算法设计与分析>课件.ppt>由会员分享,可在线阅读,更多相关<王晓东<算法设计与分析>课件.ppt(356页珍藏版)>请在人人文库网上搜索. ...

  5. 算法设计与分析(python版)-作业一

    参考教材:算法设计与分析(Python版)         作者:王秋芬 1 . 容易 (4分)2 n=O(100n ^2) 错误 2 . 容易 (3分)10=θ(log10) 正确 3 . 容易 ( ...

  6. Python 算法设计与分析 投资问题

    Python 算法设计与分析 投资问题 投资问题 题目:设有m元钱,n项投资,函数fi(x)表示将x元投入第i项项目所产生的效益,i=1,2,3,-,n.问:如何分配这m元钱,使得投资的总效益最高? ...

  7. 算法设计与分析: 5-22 魔方(Rubik's Cube)问题

    5-22 魔方(Rubik's Cube)问题 问题描述 3×3×33×3×33\times3\times3 魔方的构造如图所示.图中英文字母 U,L,F,R,B,D 分别表示魔方的 6 个面中的上面 ...

  8. 程振波 算法设计与分析_算法设计与分析

    本书按照教育部*制定的计算机科学与技术专业规范的教学大纲编写,努力与国际计算机学科的教学要求接轨.强调 算法 与 数据结构 之间密不可分的联系,因而强调融数据类型与定义在该类型上的运算于一体的抽象数据 ...

  9. C++ 算法设计与分析 地图着色问题(中国+美国)

    文章目录 中国+美国可选择地图着色问题 地图着色问题 解决方法 回溯法 队列 代码展示 美国地图着色 代码(c++) 结果 中国+美国地图着色 代码(c++) 结果 可视化 中国+美国可选择地图着色问 ...

最新文章

  1. 按一行一行的方法将一个文本文件复制到另一个文件中_大文件上的结构化数据计算示例...
  2. pycharm与python连接_pycharm2017实现python3.6与mysql的连接
  3. Java把表导出成Excel的代码
  4. 《深入理解Java虚拟机》读书笔记二
  5. iFrame左树目录
  6. freeswitch添加tls加密
  7. 深信服SCSA安全工程师题库(方便大家复习备考)
  8. MTK 三星处理器一览表
  9. Android N DisplayManager服务解析(二)
  10. 电脑的wifi天线原理_详解无线路由器天线的原理
  11. Android实现VR查看图片
  12. 托福口语_新航道_刘莹_task 3 task5
  13. win7系统安装telnet服务器,Win7怎样安装telnet服务?
  14. python svg转png_如何使用Python3实现svg转png与pdf(附转换源代码)
  15. 弘辽科技:拼多多专属推广怎么设置时间。
  16. (十八)【模电】(放大电路中的反馈)交流负反馈对放大电路性能的影响
  17. mysql jpa List_jpa查询数据库返回list
  18. 设置本计算机win7的网络参数,Win7本机IP地址设置图文教程
  19. Windows 使用技巧
  20. Twincat3 启动报错

热门文章

  1. Introduction常用句式总结 - 易智编译EaseEditing
  2. 蓝桥杯单片机零基础到国二经验分享
  3. 基于matlab人,基于MATLAB的人口预测研究
  4. 教你批量查询百世快运在途信息,并分析提前签收
  5. 聚焦IWF上海国际健身展,英派斯让娱乐和健身“智能连接”
  6. 随机过程笔记:2.谱分析
  7. 微软语音合成(tts)服务申请和调用
  8. 不是操作系统的是JAVA_在Jdbc中可以调用数据库的存储过程的接口是( )。
  9. hyk-proxy 构建于GAE之上的高性能web代理
  10. select实现connect超时连接