九宫重排  
 
时间限制: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. Phone numbers

    Phone number in Berland is a sequence of n digits. Often, to make it easier to memorize the number, ...

  2. 微信小程序 报错Setting data field "variableName" to undefined is invalid.

    Setting data field "variableName" to undefined is invalid. 将数据字段“variableName”设置为未定义是无效的. ...

  3. 增加虚拟机ubuntu的硬盘

    20150526更新验证日记: (1)首先在虚拟机中增加ubuntu的硬盘大小. (2)在ubuntu中使用Gparted软件对新的空间进行分配(傻瓜式) (3)不能直接将磁盘挂载到home下,只能先 ...

  4. (转)nodejs搭建本地http服务器

    本文转载自:http://www.cnblogs.com/shawn-xie/archive/2013/06/06/3121173.html 由于不做php相关的东西,懒得装apache,干脆利用no ...

  5. mybatis sql中的条件语句

    1.mybatis判断是否为空或null <if test="type!=null and type!=''"> AND type = #{type} </if& ...

  6. socket模型

    Socket: "主机" + "端口" = 套接字/插座; 仅仅是一个通信模型,不属于七层协议(网络协议). 一台电脑(IP)的一个应用程序(端口) 和 另一台 ...

  7. Ubuntu14.04LTS上安装Pip

    pip是一个安装和管理Python包的工具.在Pip的帮助下,你可以安装独特版本的包. 最重要的是,Pip可以通过一个“requirements”的工具来管理一个由包组成的列表和版本号. Pip很像e ...

  8. Spring MVC配置详解(2)---bai

    web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version="2 ...

  9. Identity4 Clientcredentials 自定义客户端授权验证

    看了许多教程 ,大多数都是提前定义好客户端,但是这样有个弊端,我们并不知道以后会有多少客户端.有可能从数据库读取数据,也有可能通过json文件获取,总之 各种方式. 然后 网上大多数教程都是提前定义好 ...

  10. C语言在32位和64位机器下数字数据类型的字节数取决于编译器和平台, 主要由编译器决定。

    C语言中数字数据类型的字节数 C声明 32位机器 64位机器 char 1 1 short int 2 2 int   4 4 //整型在32位和64位下都是4个字节 long int   4 8 l ...