博客
关于我
AcWing 845. 八数码(BFS)
阅读量:345 次
发布时间:2019-03-04

本文共 3249 字,大约阅读时间需要 10 分钟。

在一个3×3的网格中,1~8这8个数字和一个“x”恰好不重不漏地分布在这3×3的网格中。

例如:

1 2 3x 4 67 5 8

在游戏过程中,可以把“x”与其上、下、左、右四个方向之一的数字交换(如果存在)。

我们的目的是通过交换,使得网格变为如下排列(称为正确排列):

1 2 34 5 67 8 x

例如,示例中图形就可以通过让“x”先后与右、下、右三个方向的数字交换成功得到正确排列。

交换过程如下:

1 2 3   1 2 3   1 2 3   1 2 3x 4 6   4 x 6   4 5 6   4 5 67 5 8   7 5 8   7 x 8   7 8 x

现在,给你一个初始网格,请你求出得到正确排列至少需要进行多少次交换。

输入格式

输入占一行,将3×3的初始网格描绘出来。

例如,如果初始网格如下所示:

1 2 3

x 4 6

7 5 8

则输入为:1 2 3 x 4 6 7 5 8

输出格式

输出占一行,包含一个整数,表示最少交换次数。

如果不存在解决方案,则输出”-1”。

输入样例:

2  3  4  1  5  x  7  6  8

输出样例

19

思想:bfs的爆搜

难点:

1、状态的表示

2、距离的存储

每移动一个位置(上下左右)我们就要将这种状态下的九宫格存储起来(字符串),然后这种状态下的距离为上个状态距离+1,直到我们当前九宫格的状态和要求一致,此时就是最短修改距离,返回即可。

解释:

strs数组: 存储出现的字符串

strsh哈希表: 存储字符串出现的下标
pre数组: 存储当前字符串的父节点指针
根据strsh哈希表查找到当前字符串的下标,根据下标在pre数组中查找到父节点下标,根据父节点下标输出strs数组的值。

记录最短修改路径和他们的信息(倒叙)

12345678x

1234567x8
1234x6758
12346x758
12346875x
1234687x5
1234x8765
123x48765
123748x65
1237486x5
12374865x
12374x658
1237x4658
1237546x8
123754x68
123x54768
x23154768
2x3154768
23x154768
23415x768

19

import java.io.*;import java.util.*;class Main{    static ArrayDeque
q = new ArrayDeque
(); static HashMap
d = new HashMap<>(); static int[] dx = {-1, 1, 0, 0}, dy = {0, 0, -1, 1}; static String[] strs = new String[100010];//记录出现过的字符串 static HashMap
strsh = new HashMap<>();//存储当前字符串在数组中的下标 static int[] pre = new int[100010];//记录当前节点的父节点指针 static int idx = 0; static int res = 0;//记录成功的下标 static int bfs(String start){ q.offer(start); d.put(start, 0); strs[idx] = start;//记录当前字符串 strsh.put(start, 0); pre[idx] = -1;//记录父节点指针,根节点的父节点指针设置为-1 idx++; String end = "12345678x"; while(q.size() != 0){ String str = q.poll(); int index = strsh.getOrDefault(str, 0);//得到下标作为修改后节点的父节点 int dist = d.get(str); if(str.equals(end)){ for(int i = res - 1; i != -1; i = pre[i]){//查找祖先节点 System.out.print(strs[i] + "\n"); } return dist; } int k = str.indexOf("x"); int x = k / 3, y = k % 3; //状态转移 for(int i = 0; i < 4; ++i){ int a = x + dx[i], b = y + dy[i]; if(a >= 0 && a < 3 && b >= 0 && b < 3){ char[] chs = str.toCharArray(); char ch = chs[k]; chs[k] = chs[a * 3 + b]; chs[a * 3 + b] = ch; String str_new = String.valueOf(chs); if(!d.containsKey(str_new)){ strs[idx] = str_new;//记录当前字符串 pre[idx] = index;//记录当前字符串的父节点指针 strsh.put(str_new, idx); idx++; if(str_new.equals(end)){ res = idx; } d.put(str_new, dist + 1); q.offer(str_new); } } } } return -1; } public static void main(String[] args)throws Exception{ BufferedReader buf = new BufferedReader(new InputStreamReader(System.in)); String str = buf.readLine().replace(" ",""); System.out.print(bfs(str)); }}

转载地址:http://iure.baihongyu.com/

你可能感兴趣的文章
mudbox卸载/完美解决安装失败/如何彻底卸载清除干净mudbox各种残留注册表和文件的方法...
查看>>
mysql 1264_关于mysql 出现 1264 Out of range value for column 错误的解决办法
查看>>
mysql 1593_Linux高可用(HA)之MySQL主从复制中出现1593错误码的低级错误
查看>>
mysql 5.6 修改端口_mysql5.6.24怎么修改端口号
查看>>
MySQL 8.0 恢复孤立文件每表ibd文件
查看>>
MySQL 8.0开始Group by不再排序
查看>>
mysql ansi nulls_SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON 什么意思
查看>>
multi swiper bug solution
查看>>
MySQL Binlog 日志监听与 Spring 集成实战
查看>>
MySQL binlog三种模式
查看>>
multi-angle cosine and sines
查看>>
Mysql Can't connect to MySQL server
查看>>
mysql case when 乱码_Mysql CASE WHEN 用法
查看>>
Multicast1
查看>>
mysql client library_MySQL数据库之zabbix3.x安装出现“configure: error: Not found mysqlclient library”的解决办法...
查看>>
MySQL Cluster 7.0.36 发布
查看>>
Multimodal Unsupervised Image-to-Image Translation多通道无监督图像翻译
查看>>
MySQL Cluster与MGR集群实战
查看>>
multipart/form-data与application/octet-stream的区别、application/x-www-form-urlencoded
查看>>
mysql cmake 报错,MySQL云服务器应用及cmake报错解决办法
查看>>