自己写的 通过样例19/20
思路
用bfs对地图进行搜索,对于每一个点,对其四个方向进行搜索,用#标记是已经搜索过的,使用魔法我这里理解的就是跳两步,看是否到达终点,有局限性哈
改进的
从起点开始搜索,标记为1
从终点开始搜索,标记为2
使用魔法跳两步,看到达的地方是否与这一趟的数字不同,若不同则找到一条路,这句话的意思是说,我从起点搜一次,从终点搜一次,在从终点搜索的狮虎我每次向前考虑两步,如果前进两步后出现了1,那么表明打破这个障碍物后能找到一条路,待会试试
改进的
这个能ac
- 从起点搜一遍
- 若能找到出口则退出,反之从终点搜一遍
- 遍历地图,找障碍物,对障碍物的四个方向进行遍历,如果障碍物的四个方向中其中有两个方向是1或2那么u就是3,这也就是为什么check函数最后返回的是u==3的原因
- 这都找不到出口,那是真没有了
代码
import java.util.*;
public class Main{
static int row,col;
static int[] start;
static int[] end;
static char[][] map;
static int[][] direct = {
{0,1},
{0,-1},
{1,0},
{-1,0},
};
static int[][] magic = {
{0,2},
{0,-2},
{2,0},
{-2,0},
};
static boolean flag = false; //使用魔法标志
public static boolean checkNorm(int curX,int curY){
if(curX>row || curX<=0
|| curY>col || curY<=0
|| map[curX][curY]=='#'
)
return false;
return true;
}
public static boolean checkMagic(int curX,int curY){
boolean norm = checkNorm(curX,curY);
if(norm && curX==end[0] && curY == end[1])
return true;
return false;
}
public static boolean bfs(){
Queue<Integer[]> queue =new LinkedList<>();
queue.add(new Integer[]{start[0],start[1]});
map[start[0]][start[1]]='#';// 标记访问过了
while (!queue.isEmpty()){
Integer[] temp = queue.poll();
if(temp[0] == end[0] && temp[1] ==end[1])
return true;
for(int i=0;i<4;i++){
int curX = temp[0] + direct[i][0];
int curY = temp[1] + direct[i][1];
//尝试使用一次魔法
int magicX = temp[0] + magic[i][0];
int magicY = temp[1] + magic[i][1];
if(checkMagic(magicX,magicY)){
flag = true;
return true;
}
// 正常情况下的curX curY边界性检查
if(!checkNorm(curX,curY))
continue;
queue.add(new Integer[]{curX,curY});
map[curX][curY] = '#';// 标记访问过了
}
}
return false;
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
row = s.nextInt();
col = s.nextInt();
map = new char[row+1][col+1];
start = new int[2];
end = new int[2];
start[0] = s.nextInt();
start[1] = s.nextInt();
end[0] = s.nextInt();
end[1] = s.nextInt();
for(int i=1;i<=row;i++){
map[i] = (" "+ s.next()).toCharArray();
}
boolean res = bfs();
System.out.println(res?"Yes":"No");
s.close();
}
}
改进的
import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
static boolean res;
static int row,col;
static char[][] map;
static int[][] used;
static int[][] direct = {{0,1},{0,-1},{1,0},{-1,0}};
static int[] start = new int[2],end = new int[2];
public static void bfs(int x,int y,int c){
Queue<Integer[]> queue = new LinkedList<>();
queue.add(new Integer[]{x,y});
used[x][y]=c;
while (!queue.isEmpty()){
Integer[] poll = queue.poll();
for(int i=0;i<4;i++){
int curX = poll[0] + direct[i][0];
int curY = poll[1] + direct[i][1];
if(c==1&&curX == end[0] && curY == end[1])
{
res=true;
return;
}else if(c==2 && curX == start[0] && curY == start[1]){
res=true;
return;
}
if(curY > col || curY <=0 ||
curX > row || curX <=0 ||
map[curX][curY]=='#' || used[curX][curY]!=0)
continue;
used[curX][curY] = c;
queue.add(new Integer[]{curX,curY});
}
}
}
public static boolean check(int x,int y){
int u = 0;
for(int i=0;i<4;i++){
int curX = x + direct[i][0];
int curY = y + direct[i][1];
if(curY > col || curY <=0 ||
curX > row || curX <=0)
continue;
u|=used[curX][curY];
}
return u==3;
}
public static void main(String[] args) throws IOException {
Scanner s = new Scanner(System.in);
row = s.nextInt();
col = s.nextInt();
map = new char[row+1][col+1];
used = new int[row+1][col+1];
start[0] = s.nextInt();
start[1] = s.nextInt();
end[0] = s.nextInt();
end[1] = s.nextInt();
for(int i=1;i<=row;i++){
map[i] = (" "+s.next()).toCharArray();
}
bfs(start[0],start[1],1 );
if(res){
System.out.println("Yes");
}else{
bfs(end[0],end[1],2 );
for(int i=1;i<=row;i++){
for(int j=1;j<=col;j++){
if(map[i][j]=='#' && check(i,j))
{
System.out.println("Yes");
return;
}
}
}
System.out.println("No");
}
s.close();
}
}