九宫重排  
 
时间限制:1.0s   内存限制:256.0MB
问题描述
  如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。

  我们把第一个图的局面记为:12345678.
  把第二个图的局面记为:123.46758
  显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
  本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
 
输入格式
  输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
  输出最少的步数,如果不存在方案,则输出-1。
 
样例输入
12345678.
123.46758
 
样例输出
3
 
样例输入
13524678.
46758123.
 
样例输出
22
 
 
BFS。将字符串视作状态,将“.”视作位移点,每次向四个方向移动的同时交换字符。
 
很明显需要用到HashMap来记录状态,开始时图方便我把字符串转换成二维数组作为HashMap的键值,然后就遇到各种问题。。
首先二维数组作为键值记录的是地址而并非数组元素,所以即使是两个相同的数组代表的也是不同的键值。
其次用二维数组来进行操作效率极低。。
最终还是回到了字符串处理上,用一维来表示二维状态,仔细推敲后其实并不麻烦(详见代码)。
注意字符交换时replace用到的小技巧。
 
然后就是算法方面了,这道题用bfs显然是可做的:
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.Scanner; public class Main { static Scanner sc = new Scanner(System.in);
static String beg,end;
static int[][] t = {{1,0},{0,1},{-1,0},{0,-1}};
static HashMap<String,Integer> b = new HashMap<String,Integer>();
static class Node{
String a;
int x,s;
public Node(String a,int x,int s) {
this.a=a;
this.x=x;
this.s=s;
}
}
static ArrayDeque<Node> q = new ArrayDeque<Node>(); static int bfs(int bx,int ex) { b.put(end, -1);
if(b.get(beg)!=null) return 0;
b.put(beg, 0);
q.offerLast(new Node(beg,bx,0));
while(q.size()>0) {
String a=q.peekFirst().a;
int x=q.peekFirst().x/3;
int y=q.peekFirst().x%3;
int s=q.peekFirst().s;
q.pollFirst();
for(int i=0;i<4;i++) {
int tx=x+t[i][0];
int ty=y+t[i][1];
if(tx<0||ty<0||tx>=3||ty>=3) continue;
char tt=a.charAt(tx*3+ty);
String ta=a;
ta=ta.replace(tt, '!');
ta=ta.replace('.', tt);
ta=ta.replace('!', '.');
if(b.get(ta)!=null){
if(b.get(ta)==-1) return s+1;
continue;
}
b.put(ta, s+1);
q.offerLast(new Node(ta,tx*3+ty,s+1));
}
}
return -1;
} public static void main(String[] args) { beg = sc.next();
end = sc.next();
int bx=0,ex=0;
for(int i=0;i<9;i++) {
if(beg.charAt(i)=='.'){
bx=i;
break;
}
}
for(int i=0;i<9;i++) {
if(end.charAt(i)=='.'){
ex=i;
break;
}
}
System.out.println(bfs(bx,ex));
} }

优化前

但官网提交显示只过了80%数据
 
因此需要想到使用双起点bfs优化,起点终点一起搜,大大减少了分支情况。
碰头时两边步数+当前1即为最终解。
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.Scanner; public class Main { static Scanner sc = new Scanner(System.in);
static String beg,end;
static int[][] t = {{1,0},{0,1},{-1,0},{0,-1}};
static HashMap<String,Integer> bb = new HashMap<String,Integer>();
static HashMap<String,Integer> be = new HashMap<String,Integer>();
static class Node{
String a;
int x,s,m;
public Node(String a,int x,int s,int m) {
this.a=a;
this.x=x;
this.s=s;
this.m=m;
}
}
static ArrayDeque<Node> q = new ArrayDeque<Node>(); static int bfs(int bx,int ex) { if(beg.equals(end)) return 0;
bb.put(beg, 0);be.put(end, 0);
q.offerLast(new Node(beg,bx,0,1));
q.offerLast(new Node(end,ex,0,2));
while(q.size()>0) {
String a=q.peekFirst().a;
int x=q.peekFirst().x/3;
int y=q.peekFirst().x%3;
int s=q.peekFirst().s;
int m=q.peekFirst().m;
q.pollFirst();
for(int i=0;i<4;i++) {
int tx=x+t[i][0];
int ty=y+t[i][1];
if(tx<0||ty<0||tx>=3||ty>=3) continue;
char tt=a.charAt(tx*3+ty);
String ta=a;
ta=ta.replace(tt, '!');
ta=ta.replace('.', tt);
ta=ta.replace('!', '.');
if(m==1){
if(bb.get(ta)!=null) continue;
if(be.get(ta)!=null) return be.get(ta)+s+1;
bb.put(ta, s+1);
}
else{
if(be.get(ta)!=null) continue;
if(bb.get(ta)!=null) return bb.get(ta)+s+1;
be.put(ta, s+1);
}
q.offerLast(new Node(ta,tx*3+ty,s+1,m));
}
}
return -1;
} public static void main(String[] args) { beg = sc.next();
end = sc.next();
int bx=0,ex=0;
for(int i=0;i<9;i++) {
if(beg.charAt(i)=='.'){
bx=i;
break;
}
}
for(int i=0;i<9;i++) {
if(end.charAt(i)=='.'){
ex=i;
break;
}
}
System.out.println(bfs(bx,ex));
} }

优化后

2013年第四届蓝桥杯国赛 九宫重排(HashMap+双BFS优化)的更多相关文章

  1. 2013年第四届蓝桥杯国赛试题(JavaA组)

    1.结果填空 (满分12分)2.结果填空 (满分15分)3.结果填空 (满分10分)4.程序设计(满分16分)5.程序设计(满分20分)6.程序设计(满分27分) 1.标题:填算式 请看下面的算式: ...

  2. 2013年第四届蓝桥杯省赛试题(JavaA组)

    1.结果填空 (满分3分)2.结果填空 (满分5分)3.结果填空 (满分6分)4.结果填空 (满分13分)5.代码填空 (满分5分)6.代码填空 (满分10分)7.程序设计(满分4分)8.程序设计(满 ...

  3. 第九届蓝桥杯国赛+第二天的第11届acm省赛的总结

    第九届蓝桥杯国赛+第二天的第11届acm省赛的总结 25号坐的去北京的火车,10个小时的火车,然后挤了快两个小时的地铁,最终达到了中国矿业大学旁边的订的房间.12个小时很难受,晕车症状有点严重,吃了快 ...

  4. 带分数--第四届蓝桥杯省赛C++B/C组

    第四届蓝桥杯省赛C++B/C组----带分数 思路: 1.先枚举全排列 2.枚举位数 3.判断是否满足要求 这道题也就是n=a+b/c,求出符合要求的abc的方案数.进行优化时,可以对等式进行改写,改 ...

  5. 2018年第九届蓝桥杯国赛总结(JavaB组)

    懒更,之前的删了补一个国赛总结 记yzm10的第一次国赛(赛点:首都经贸大学) 第一次就拿到了国一,运气不要太好~(同组lz学长豪取国特orz) 从省赛一路水过来,总算有了点成绩.其实最后一题有些遗憾 ...

  6. 2019年第十届蓝桥杯国赛总结(JavaA组)

    JavaA组国二,可以报销了~ JA死亡之组可不是盖的,rank12的排名还是拿不到国一啊(只有五个.. 出成绩的一刻波澜不惊,毕竟去年有国一了不慌哈哈哈 不过对我来说这个结果还算意料之外吧,毕竟大三 ...

  7. 2015年第六届蓝桥杯国赛试题(JavaA组)

    1.结果填空 (满分15分)2.结果填空 (满分35分)3.代码填空 (满分31分)4.程序设计(满分41分)5.程序设计(满分75分)6.程序设计(满分103分) 1.标题:胡同门牌号 小明家住在一 ...

  8. 蓝桥杯 历届试题 九宫重排 (bfs+康托展开去重优化)

    Description 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的 ...

  9. 蓝桥杯OJ PREV-19 九宫重排

    题目描写叙述:   历届试题 九宫重排   时间限制:1.0s   内存限制:256.0MB        问题描写叙述 如以下第一个图的九宫格中,放着 1~8 的数字卡片.另一个格子空着.与空格子相 ...

随机推荐

  1. (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令

    (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢-) 接上一节:(C#)Windows Shell 外壳编程系列3 - 上下文菜单(iContextMenu)(一)右键菜单 上一节说到如 ...

  2. 蓝桥杯 基础练习 BASIC-24 龟兔赛跑预测

    基础练习 龟兔赛跑预测   时间限制:1.0s   内存限制:512.0MB 问题描述 话说这个世界上有各种各样的兔子和乌龟,但是研究发现,所有的兔子和乌龟都有一个共同的特点——喜欢赛跑.于是世界上各 ...

  3. 蓝桥杯 算法训练 ALGO-156 表达式计算

    算法训练 表达式计算   时间限制:1.0s   内存限制:256.0MB 问题描述 输入一个只包含加减乖除和括号的合法表达式,求表达式的值.其中除表示整除. 输入格式 输入一行,包含一个表达式. 输 ...

  4. Mina APR传输与串口传输讲解---zhengli

    原文地址:Mina Transports(Apache Mina user guide Chapter6 Transport) 1.1.1.APR传输 1.1.1.1.介绍 APR (Apache P ...

  5. Java程序开发中的简单内存分析

    首先说明内存总体分为了4个部分, 包括 1.stack segment (栈区存储基本数据类型的局部变量,对象的引用名) 2.heap segment(堆区,一般用于存储java中new 出来的对象) ...

  6. Task用法(2)-任务等待wait

    1.Wait 用法   默认情况下,Task 是有线程池中的异步线程执行,是否执行完成,可以通过Task的的属性IsCompleted 来判断,  如果想在子线程工作完成之后,在进行后续主线程工作可以 ...

  7. mybatis如何防止sql注入(1)

    sql注入大家都不陌生,是一种常见的攻击方式,攻击者在界面的表单信息或url上输入一些奇怪的sql片段,例如“or ‘1’=‘1’”这样的语句,有可能入侵参数校验不足的应用程序.所以在我们的应用中需要 ...

  8. 此上下文中不允许异步操作。启动异步操作的页必须将 Async 特性设置为 true,并且异步操作只能在 PreRenderComplete 事件之前的页上启动。

    <%@ Page Language="C#" AutoEventWireup="true" ...... Async="true" % ...

  9. Windows 常见进程

    alg.exe描述: alg.exe是Windows系统的一个重要进程,它的功能是用来处理 Internet 连接共享及防火墙,最好不要结束这个进程.taskmgr.exe描述: Windowsxp ...

  10. windows异常演示,指定异常类型,然后生成异常

    #include "stdafx.h"#include <Windows.h>#include <float.h> DWORD Filter (LPEXCE ...