杭电1254java实现(双bfs 优先队列)

简介: 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图2)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动.现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格.

推箱子



推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图2)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动.


现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格.


Input


输入数据的第一行是一个整数T(1<=T<=20),代表测试数据的数量.然后是T组测试数据,每组测试数据的第一行是两个正整数M,N(2<=M,N<=7),代表房间的大小,然后是一个M行N列的矩阵,代表房间的布局,其中0代表空的地板,1代表墙,2代表箱子的起始位置,3代表箱子要被推去的位置,4代表搬运工的起始位置.


Output


对于每组测试数据,输出搬运工最少需要推动箱子多少格才能帮箱子推到指定位置,如果不能推到指定位置则输出-1.


Sample Input


1

5 5

0 3 0 0 0

1 0 1 4 0

0 0 1 0 0

1 0 2 0 0

0 0 0 0 0


Sample Output


4


思路:把问题拆分


1:如果单看箱子的移动,就是一个bfs求最短。


2:但是这里多了条件就是需要人去推,那么在箱子移动就要记录小人移动的位置,小人推箱子前的位置和需要在的位置推箱子,要判断能否到达,这又是一个bfs。要注意小人除了箱子的位置和墙奇特都可以走。要判断小人是否越界,可走。


3:这里的人和箱子的位置是会变的,然而他们的初始位置是标记其他数字不是0,最好将他的数字改成0,使用参数单独标记其位置。


4:人的遍历要记忆一次遍历,因为我要求的只是到达。但是箱子的遍历要记录不是走一次,一个位置可走两次。可能箱子卡在门口推出去,人再内,人在推出去推进来。


5:箱子要用优先队列优化,标记为推得次数。


代码如下:


import java.util.ArrayDeque;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
public class 杭电1254 {
  static int x1,y1,x2,y2,x3,y3,m,n;//人 箱子 结束点
  static int x[]= {0,1,0,-1};
  static int y[]= {1,0,-1,0};
  static int a[][];//存储值
  static boolean jud=false;
   public static void main(String[] args) {
     Scanner sc=new Scanner(System.in);
     int t=sc.nextInt();//测试数据
     for(int t1=0;t1 q2=new PriorityQueue(comepare);//优先队列
       q2.add(new xiang(x2,y2,x1,y1,0));//加入第一个箱子和人的位子
       while(!q2.isEmpty())
       {
         xiang xiang=q2.poll();
         int x4=xiang.xx;int y4=xiang.yx;//箱子
         int x5=xiang.xr;int y5=xiang.yr;//ren
         if(x4==x3&&y4==y3){System.out.println(xiang.time);jud=true;break;}
         else for(int i=0;i<4;i )
         {
           if(x4 x[i]>=0&&x4 x[i]=0&&y4 y[i]=0&&x4-x[i]=0&&y4-y[i]2)//允许它来回一次,也就是这个点可以走两次
                 mark[x4 x[i]][y4 y[i]]=true;
               }
               }
             }
           }
         }
       }
       if(!jud) {System.out.println(-1);}
       jud=false;     
     }
   }
public static boolean move(int x11,int y11,int x21,int y21,int x41,int y41 )//起始点,末尾,箱子
{
  boolean b[][]=new boolean[m][n];
  Queue q1=new ArrayDeque();
  b[x11][y11]=true;//起点和箱子当作遍历过
  b[x41][y41]=true;
  q1.add(new zuobiao(x11,y11)); 
  while(!q1.isEmpty())
  {
    zuobiao zuo=q1.poll();
    int x31=zuo.x;int y31=zuo.y;
    if(x31==x21&&y31==y21){return true;}
    else for(int i=0;i<4;i )
    {
      if(x31 x[i]>=0&&x31 x[i]=0&&y31 y[i]comepare=new Comparator()
{
  public int compare(xiang arg0, xiang arg1) {
    return(int) (arg0.time-arg1.time);
  }};
private  static class xiang
 {
    int xx;
    int yx;//箱子
    int xr;
    int yr;//人
    int time;
    public xiang(int xx,int yx,int xr,int yr,int time)
    {
      this.xx=xx;
      this.yx=yx;
      this.xr=xr;
      this.yr=yr;
      this.time=time;
    }
 }
private static class zuobiao
{
  int x;
  int y;
  public zuobiao(int x,int y)
  {
    this.x=x;
    this.y=y;
  }   
}
}
目录
相关文章
企业局域网监控软件中 Java 优先队列算法的核心优势
企业局域网监控软件是数字化时代企业网络安全与高效运营的基石,犹如一位洞察秋毫的卫士。通过Java实现的优先队列算法,它能依据事件优先级排序,确保关键网络事件如异常流量、数据泄露等被优先处理,保障系统稳定与安全。代码示例展示了如何定义网络事件类并使用PriorityQueue处理高优先级事件,尤其在面对疑似风险时迅速启动应急措施。这一核心技术助力企业在复杂网络环境中稳健前行,护航业务腾飞。
72 32
Java 中的优先队列 PriorityQueue 详解
【10月更文挑战第22天】优先队列 PriorityQueue 是一种非常实用的数据结构,在许多场景中都能发挥重要作用。通过深入了解其特点和用法,我们可以更好地利用它来解决实际问题。
228 13
|
9月前
|
杭电 OJ 1010-1019 Java解法(未更新完毕)
杭电 OJ 1010-1019 Java解法(未更新完毕)
41 1
Java数据结构与算法:优先队列
Java数据结构与算法:优先队列
Java数据结构与算法:图算法之广度优先搜索(BFS)
Java数据结构与算法:图算法之广度优先搜索(BFS)
|
9月前
|
杭电acm1201 18岁生日 Java解法 时间类
杭电acm1201 18岁生日 Java解法 时间类
42 0
|
9月前
|
杭电 OJ 1000-1009 Java解法
杭电 OJ 1000-1009 Java解法
38 0
|
9月前
|
杭电acm2018 母牛的故事 Java解法 经典递归
杭电acm2018 母牛的故事 Java解法 经典递归
52 0
|
9月前
|
杭电acm1013 Digital Roots 数字根 Java解法 高精度
杭电acm1013 Digital Roots 数字根 Java解法 高精度
43 0
|
1月前
|
【Java并发】【线程池】带你从0-1入门线程池
欢迎来到我的技术博客!我是一名热爱编程的开发者,梦想是编写高端CRUD应用。2025年我正在沉淀中,博客更新速度加快,期待与你一起成长。 线程池是一种复用线程资源的机制,通过预先创建一定数量的线程并管理其生命周期,避免频繁创建/销毁线程带来的性能开销。它解决了线程创建成本高、资源耗尽风险、响应速度慢和任务执行缺乏管理等问题。
166 60
【Java并发】【线程池】带你从0-1入门线程池
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等