问题描述
试题编号: | 201604-4 |
试题名称: | 游戏 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 小明在玩一个电脑游戏,游戏在一个n×m的方格图上进行,小明控制的角色开始的时候站在第一行第一列,目标是前往第n行第m列。 输入格式 输入的第一行包含三个整数n, m, t,用一个空格分隔,表示方格图的行数n、列数m,以及方格图中有危险的方格数量。 输出格式 输出一个整数,表示小明最快经过几个时间单位可以过关。输入数据保证小明一定可以过关。 样例输入 3 3 3 样例输出 6 样例说明 第2行第1列时刻1是危险的,因此第一步必须走到第1行第2列。 评测用例规模与约定 前30%的评测用例满足:0 < n, m ≤ 10,0 ≤ t < 99。 |
这是一个求最短路径问题,用BFS。巧妙的是,在用来判断是否已经访问的visit数组上又加了时间维度,即visit是一个三维数组。
还有,数组visited[][][]的第3维坐标之所以为300+1,是计算出来的。从左上角到右下角最多走200步,时间范围a,b<=100,那么安全走到右下角使用的最多时间<=300,下标0不使用,所以是300+1。
import java.util.*;
public class Main {
static Scanner sc = new Scanner(System.in);
static int n,m,t;//行,列,危险点个数
static int[][] direction={{-1,0},{1,0},{0,-1},{0,1}};
static boolean[][][] visit;
static class P{
int r;
int c;
int step;
public P() {
super();
}
public P(int r, int c, int t) {
super();
this.r = r;
this.c = c;
this.step = t;
}
}
static int bfs(){
ArrayList<P> list=new ArrayList<P>();//队列
P start=new P(1,1,0);//起点
list.add(start);
while(!list.isEmpty()){
P front=list.get(0);
list.remove(0);
if(front.r==n&&front.c==m)//到达终点则结束
return front.step;
for(int i=0;i<4;i++){//遍历当前点的四个方向
P p=new P();
p.r=front.r+direction[i][0];
p.c=front.c+direction[i][1];
if(p.r<1||p.r>n||p.c<1||p.c>m)//行列越界则跳过
continue;
if(visit[p.r][p.c][p.step])//已经访问过的点不再访问
continue;
/*
* 向前访问
*/
p.step=front.step+1;
visit[p.r][p.c][p.step]=true;
list.add(p);
}
}
return 0;
}
public static void main(String[] args) {
n=sc.nextInt();
m=sc.nextInt();
t=sc.nextInt();
visit=new boolean[n+1][m+1][300+1];
for(int i=0;i<t;i++){
int r=sc.nextInt();
int c=sc.nextInt();
int a=sc.nextInt();
int b=sc.nextInt();
for(int j=a;j<=b;j++)
visit[r][c][j]=true;//true表示不能访问
}
System.out.println(bfs());
}
}