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 ...
随机推荐
- 单断言VS多断言
STST 想和大家讨论一下,一个测试用例里只做一个断言还是一个用例里做多个相关的断言 比如有一个查询函数Query(id) 返回[姓名,性别,年龄] 那么是在一个测试用例里对这三个属性进行断言好? 还 ...
- HDU 3339 In Action【最短路+01背包模板/主要是建模看谁是容量、价值】
Since 1945, when the first nuclear bomb was exploded by the Manhattan Project team in the US, the n ...
- 洛谷——P3908 异或之和
P3908 异或之和 题目描述 求1 \bigoplus 2 \bigoplus\cdots\bigoplus N1⨁2⨁⋯⨁N 的值. A \bigoplus BA⨁B 即AA , BB 按位异或. ...
- MYSQL注入天书之导入导出介绍
Background-3 导入导出相关操作的讲解 load_file()导出文件 Load_file(file_name):读取文件并返回该文件的内容作为一个字符串. 使用条件: A.必须有权限读取并 ...
- BestCoder Round #65 (ZYB's Premutation)
ZYB's Premutation Accepts: 220 Submissions: 983 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...
- 安卓 内存泄漏检测工具 LeakCanary 使用
韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com 配置 build.gradle dependencies { debugCompile 'com ...
- 2016ACM-ICPC网络赛北京赛区 1001 (trie树牌大模拟)
[题目传送门] 1383 : The Book List 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 The history of Peking University ...
- hdu 3547 (polya定理 + 小高精)
DIY CubeTime Limit: 2000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Sub ...
- SPOJ Time Limit Exceeded(高维前缀和)
[题目链接] http://www.spoj.com/problems/TLE/en/ [题目大意] 给出n个数字c,求非负整数序列a,满足a<2^m 并且有a[i]&a[i+1]=0, ...
- 【分块】【暴力】XVII Open Cup named after E.V. Pankratiev Grand Prix of Moscow Workshops, Sunday, April 23, 2017 Problem I. Rage Minimum Query
1000w的数组,一开始都是2^31-1,然后经过5*10^7次随机位置的随机修改,问你每次的全局最小值. 有效的随机修改的期望次数很少,只有当修改到的位置恰好是当前最小值的位置时才需要扫一下更新最小 ...