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 ...
随机推荐
- centos部署Django项目的前提工作
从安装python到django项目的部署上线.是相当详细了,中间也没有出现什么幺蛾子.很赞!!! https://blog.csdn.net/u011798443/article/details/8 ...
- POJ 1258 + POJ 1287 【最小生成树裸题/矩阵建图】
Farmer John has been elected mayor of his town! One of his campaign promises was to bring internet c ...
- 29、Flask实战第29天:cms用户名渲染和注销功能实现
这节来完成用户名渲染和注销的功能,目前用户名在前端页面是写死的,我们需要动态的展示出来 用户名渲染 实现用户名动态展示,其中一种方法就是在视图函数,根据session信息,获取到user id,通过该 ...
- [Nescafé41]异化多肽(多项式求逆元)
2015年的题,应该是将形式幂级数引入国内的元老级题目. 大意:给定一个大小为m的正整数序列和n,问有多少种选法可以凑成n,每个数可以选多次,种类不同算不同方案.$n,m,C \leqslant 10 ...
- 20162318 实验一《Java开发环境的熟悉》实验报告
北京电子科技学院(BESTI) 实 验 报 告 课程:程序设计与数据结构 班级:1623班 姓名:张泰毓 成绩:2分 指导老师:娄老师.王老师 实验日期:2017年3月17日 实验密级:非密级 实验器 ...
- dom操作 属性操作 样式操作
jQuery DOM操作 1 插入子元素 append('<img>') 插后面 被插入元素调用 appendTo('<img scr="...">') 新 ...
- 误改sudoers的访问权限后的修复
sudo: /etc/sudoers is mode 0777, should be 0440"问题的解决方法 ubuntu进入单用户模式,修改sudoers权限,修改root密码 1.重 ...
- 设置Eclipse编码方式
1.windows->Preferences...打开"首选项"对话框,左侧导航树,导航到 general->Workspace,右侧Text file encodin ...
- kong添加upstream
整理的文档比较早,kong版本可能是0.10.3版本.详情请看官网最新文档 准备 使用kong代理后端请求 1.开放几个接口如下: 本地请求1:http://aaa.wyc.com:8888/aaa ...
- [转] Ext Grid (ExtJs)上的单击以及双击事件
例1: 1.双击 var cb = new Ext.grid.RowSelectionModel({ singleSelect:true //如果值是false,表明可以选择多行:否则只能选择一行 } ...