Eleven puzzle_hdu_3095(双向广搜).java
Eleven puzzle
Time Limit: 20000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 463 Accepted Submission(s): 111
The tile in black means it’s empty
Each step you can move only one tile.
Here comes the problem.How many steps at least it required to done the game.
Every case contains five lines to describe the initial status of the board. 0 means empty.
It’s confirmed that the board is legal.
2
1 0 3
4 5 6 7 8
9 0 11
10
0
1 2 3
4 5 6 7 8
9 10 11
0
0
11 10 9
8 7 6 5 4
3 2 1
0
0
No solution!
//8953704 2013-08-15 15:45:09 Accepted 3095 2562MS 27052K 6524 B Java zhangyi
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Scanner; public class Hdu3095 {
private static Map<String,Integer> smap = new HashMap<String,Integer>(); //存储从初始状态搜索所到达的状态
private static Map<String, Integer> emap = new HashMap<String, Integer>();//存储从目的状态搜索所到达的状态
private static Status sStatus = null; //初始状态
private static Status eStatus = null;//目的状态
private static int [][] dirs = new int[][]{{1,0},{-1,0},{0,-1},{0,1}}; //方向
private static Queue<Status> sq = new ArrayDeque<Status>();
private static Queue<Status> eq = new ArrayDeque<Status>();
private final static Integer maxLevel = 10;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int cases = in.nextInt();
while(cases-->0){
inputData(in);
if(eStatus.getStatus().equals(sStatus.getStatus())){//如果初始状态等于目的状态,输出0
System.out.println(0);
}else{
emap.put(eStatus.getStatus(), 0);
smap.put(sStatus.getStatus(), 0);
int step = doublcBFS(sq,eq);
if(step == -1 || step > 20){
System.out.println("No solution!");
}else{
System.out.println(step);
}
}
}
}
/**
* 输入数据
* @param in
*/
private static void inputData(Scanner in){
initResourse();
int value = 0;
sStatus.map[1][3] = in.nextInt();
eStatus.map[1][3] = value++;
for(int i = 2; i <= 4; ++i){
sStatus.map[2][i] = in.nextInt();
eStatus.map[2][i] = value++;
}
for(int i = 1; i <= 5; ++i){
sStatus.map[3][i] = in.nextInt();
eStatus.map[3][i] = value++;
}
for(int i = 2; i <= 4; ++i){
sStatus.map[4][i] = in.nextInt();
eStatus.map[4][i] = value++;
}
sStatus.map[5][3] = in.nextInt();
eStatus.map[5][3] = 0;
smap.clear();
emap.clear();
sStatus.initPoint();
eStatus.initPoint();
sq.clear();
eq.clear();
sq.add(sStatus);
eq.add(eStatus);
} /**
* 初始化数据
*/
private static void initResourse(){
sStatus = new Status();
eStatus = new Status();
for(int i = 0;i < sStatus.map.length; ++i){
Arrays.fill(sStatus.map[i], -1);
Arrays.fill(eStatus.map[i], -1);
}
} /**
* 双向搜索函数
* @param sq 初始状态搜索所需要的队列
* @param eq 目的状态搜索所需要的队列
* @return 初始状态到达目的状态所需要的最小步数,如果在maxLevel数值之内没有结果,则返回-1
*/
private static int doublcBFS(Queue<Status> sq, Queue<Status> eq){
int x, y;
while(!sq.isEmpty()||!eq.isEmpty()){
if(!sq.isEmpty()){ //初始状态搜索
Status s = sq.poll();
for(int i = 0; i < s.points.size(); ++i ){
Point p = s.points.get(i);
for(int j = 0; j < dirs.length; ++j){
x = p.x + dirs[j][0];
y = p.y + dirs[j][1];
if(s.map[x][y] == -1 || s.map[x][y] == 0){
continue;
}
int [][] ms = copyArray(s.map); ms[p.x][p.y] = ms[x][y];
ms[x][y] = 0; Status status = new Status();
status.map = ms;
status.points.add(new Point(x,y));
status.points.add(s.points.get((i+1)%2).copyPoint());
status.level = s.level + 1;
String ss = status.getStatus();
if(emap.containsKey(ss)){ //如果与目的状态搜索到的状态相遇,刚返回步数
return emap.get(ss) + status.level;
}
if(!smap.containsKey(ss) && s.level <= maxLevel){
smap.put(ss, status.level);
sq.add(status);
}
}
}
}
if(!eq.isEmpty()){ //目的状态搜索
Status s = eq.poll();
for(int i = 0; i < s.points.size(); ++i ){
Point p = s.points.get(i);
for(int j = 0; j < dirs.length; ++j){
x = p.x + dirs[j][0];
y = p.y + dirs[j][1];
if(s.map[x][y] == -1 || s.map[x][y] == 0){
continue;
}
int [][] ms = copyArray(s.map);
ms[p.x][p.y] = ms[x][y];
ms[x][y] = 0; Status status = new Status();
status.map = ms;
status.points.add(new Point(x,y));
status.points.add(s.points.get((i+1)%2).copyPoint());
status.level = s.level + 1;
String ss = status.getStatus();
if(smap.containsKey(ss)){//如果与初始状态搜索到的状态相遇,刚返回步数
return smap.get(ss) + status.level;
}
if(!emap.containsKey(ss) && s.level <= maxLevel){
emap.put(ss, status.level);
eq.add(status);
}
}
}
}
}
return -1;
} /**
* 打印一个二维数组
* @param map
*/
private static void show(int [][] map){
StringBuilder sb = new StringBuilder();
for(int i = 1; i < map.length - 1; ++i){
for(int j = 1; j < map[i].length - 1; ++j){
if(map[i][j] == -1){
sb.append(' ');
}else{
sb.append(map[i][j]);
}
}
sb.append('\n');
}
System.out.println(sb.toString());
} /**
* 拷贝一个二维数组
* @param map
* @return
*/
private static int[][] copyArray(int [][] map){
int [][] m = new int[map.length][map[0].length];
for(int i = 0; i < map.length; ++i){
System.arraycopy(map[i],0,m[i],0,map[i].length);
}
return m;
}
} /**
* 存储状态
* @author Administrator
*
*/
class Status{
final static int N = 7;
int [][] map; //当前地图
List<Point> points; //当前0点坐标
int level = 0; //到达当前状态所需步数
public Status(){
map = new int[N][N];
points = new ArrayList<Point>();
level = 0;
}
public Status(int [][] map, List<Point> points, int level){
this.map = map;
this.points = points;
this.level = level;
}
public void initPoint(){
for(int i = 1; i < map.length -1; ++i){
for(int j = 1; j < map[i].length - 1; ++j){
if(map[i][j] == 0){
points.add(new Point(i,j));
}
}
}
} /**
* 返回一个可唯一标识当前状态的字符串
* @return
*/
public String getStatus(){
StringBuilder sb = new StringBuilder();
for(int i = 1; i < map.length -1; ++i){
for(int j = 1; j < map[i].length -1; ++j){
if(map[i][j] != -1){
sb.append(map[i][j]);
sb.append(',');
}
}
}
return sb.toString();
}
}
/**
* 坐标
* @author Administrator
*
*/
class Point{
int x;
int y;
public Point(){ }
public Point(int x, int y){
this.x = x;
this.y = y;
}
/**
* 拷贝一个坐标
* @return
*/
public Point copyPoint(){
Point p = new Point();
p.x = x;
p.y = y;
return p;
}
}
双向广搜
Eleven puzzle_hdu_3095(双向广搜).java的更多相关文章
- HDU--杭电--1195--Open the Lock--深搜--都用双向广搜,弱爆了,看题了没?语文没过关吧?暴力深搜难道我会害羞?
这个题我看了,都是推荐的神马双向广搜,难道这个深搜你们都木有发现?还是特意留个机会给我装逼? Open the Lock Time Limit: 2000/1000 MS (Java/Others) ...
- 双向广搜 POJ 3126 Prime Path
POJ 3126 Prime Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16204 Accepted ...
- 双向广搜 codevs 3060 抓住那头奶牛
codevs 3060 抓住那头奶牛 USACO 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 黄金 Gold 题目描述 Description 农夫约翰被告知一头逃跑奶牛 ...
- 双向广搜+hash+康托展开 codevs 1225 八数码难题
codevs 1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Yours和zero在研究A*启 ...
- 【双向广搜+逆序数优化】【HDU1043】【八数码】
HDU上的八数码 数据强的一B 首先:双向广搜 先处理正向搜索,再处理反向搜索,直至中途相遇 visit 和 队列都是独立的. 可以用一个过程来完成这2个操作,减少代码量.(一般还要个深度数组) 优化 ...
- nyoj 523 双向广搜
题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=523 #include<iostream> #include<cstd ...
- poj 3131 Cubic Eight-Puzzle 双向广搜 Hash判重
挺不错的题目,很锻炼代码能力和调试能力~ 题意:初始格子状态固定,给你移动后格子的状态,问最少需要多少步能到达,如果步数大于30,输出-1. 由于单向搜索状态太多,搜到二十几就会爆了,所以应该想到双向 ...
- 万圣节后的早晨&&九数码游戏——双向广搜
https://www.luogu.org/problemnew/show/P1778 https://www.luogu.org/problemnew/show/P2578 双向广搜. 有固定起点终 ...
- Eight_pku_1077(广搜).java
Eight Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 21718 Accepted: 9611 Special ...
随机推荐
- gvim 编辑器配置
"关才兼容模式 set nocompatible "模仿快捷键,如:ctrt+A 全选.Ctrl+C复制. Ctrl+V 粘贴等 source $VIMRUNTIME/vimrc_ ...
- 常用的phpstorm快捷键总结(带截屏版)
常用的phpstorm快捷键总结(带截屏版) 目 录 PhpStorm的快捷键有10类 1.编辑相关 2.搜索/替换 3.被使用搜索 4.项目运行 5.debug相关 6.导航相关 7.重构相关 8. ...
- 定位所用的class
方案 为解决类冲突,我们可以使用下述的方案定位一个class所在的位置 ClassName. package cn.j2se.junit.classpath; import static org.ju ...
- 丑数(LintCode)
丑数 设计一个算法,找出只含素因子3,5,7 的第 k大的数. 符合条件的数如:3,5,7,9,15...... 您在真实的面试中是否遇到过这个题? Yes 样例 如果k=4, 返回 9 挑战 要求时 ...
- cobol COMP-3最后1位
"C" hex is positive, "D" hex is negative, and "F" hex is unsigned.
- Linux基础系列-Day2
基础命令(文件内容管理) 1.cat:在当前终端显示文本文件内容 格式:cat [文件路径] -n 从1开始对所有输出的行数编号 -b 和-n相似,只不过对于空白行不编号:2.head:从文件内容开头 ...
- uva 10910(子集和问题)
Marks Distribution Time limit: 3.000 seconds In an examination one student appeared in N subjects an ...
- ES5 的 Array
1: Array.isArray判断是否为数组 Array.isArray([1, 2, 3]); // true Array.isArray({foo: 123}); // false // Pol ...
- JZYZOJ1372 [noi2002]荒岛野人 扩展欧几里得
http://172.20.6.3/Problem_Show.asp?id=1372 想法其实很好想,但是我扩展欧几里得还是用得不熟练,几乎是硬套模板,大概因为今天一个下午状态都不大好.扩展欧几里得算 ...
- JZYZOJ1390【noi2001】炮兵阵地 状压DP
http://172.20.6.3/Problem_Show.asp?id=1390 需要储存该行和上一行两个状态.通过观察规则可以发现条件允许的状态很少(相邻两个至少空两格),据此可以减少状态数量, ...