一共兩個題。筆試時先通讀了兩個題的題目。因爲第二題有思路覺得簡單就先寫的第二題。結果20分鐘寫完代碼,挑了30分鐘bug,都沒搞出來,最後坑在±號上。
根據記憶上題目:給你一個迷宮,包括一個起點‘S’和一個終點‘E’,‘#’表示障礙,不可到達的位置,‘.'表示可以到達的位置,另外你可以跳躍,跳躍的規則是從一個點跳到他中心對稱的那個點上,最多跳躍5次,求從起點到達終點的最短路徑長度。我清楚的記得,題目中描述的中心對稱的含義是:點A(x,y) 中心對稱的格子B(x1,y1) 滿足x+x1=n+1且y+y1=m+1這個關係。
那不應該是x1=n+1-x且y1=m+1-y才符合題意嗎。所以我的代碼中就是這麼做的。然而筆試後去牛客上逛了別人的思路,才知道,後面給的樣例中他們的關係是x1=n-1-x;y1=m-1-y!竟然是減!
在筆試時,我用的dfs寫的,如果我把加減號改過來,即使是思路對,也有可能超時,這是我dfs的代碼:
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
/**
* Created by fangjiejie on 2020/3/23.
*/
public class Title2 {
public static int n;
public static int m;
public static int minCost =Integer.MAX_VALUE;
public static boolean [][]book;
public static char a[][];
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
n=scanner.nextInt();
m=scanner.nextInt();
a=new char[n][m];
book=new boolean[n][m];
scanner.nextLine();
for(int i=0;i<n;i++){
String tmp=scanner.nextLine();
for(int j=0;j<m;j++){
a[i][j]=tmp.charAt(j);
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(a[i][j]=='S'){
dfs(i,j,0,5);
}
}
}
System.out.println(minCost==Integer.MAX_VALUE?-1:minCost);
// System.out.println(4);
}
static int visitX[]=new int[]{0,0,1,-1};
static int visitY[]=new int[]{1,-1,0,0};
public static void dfs(int i,int j,int curCost,int flyCount){
if(i<0||i>=n||j<0||j>=m||book[i][j]||a[i][j]=='#') return;
if(a[i][j]=='E'){
minCost=Math.min(minCost,curCost);
return;
}
book[i][j]=true;
for(int k=0;k<4;k++){
int x=i+visitX[k];
int y=j+visitY[k];
dfs(x,y,curCost+1,flyCount);
}
if(flyCount>0){
int x=n-1-i;//就是坑在了這裏!題目裏給的+,樣例中是-。
int y=m-1-j;
dfs(x,y,curCost+1,flyCount-1);
}
book[i][j]=false;
}
}
都怪自己沒有研讀題目,沒有注意到給的樣例
事後覺得用dfs寫即使提交系統也有可能超時,也不能通過100%,因爲是求最短路徑,所以我用bfs又寫了一遍。附上我的bfs代碼:
class Mi{
static class Node{
int x;
int y;
int flyCount;
public Node(int x, int y, int flyCount) {
this.x = x;
this.y = y;
this.flyCount = flyCount;
}
}
public static int n;
public static int m;
public static boolean [][]book;
public static char a[][];
static int visitX[]=new int[]{0,0,1,-1};
static int visitY[]=new int[]{1,-1,0,0};
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
n=scanner.nextInt();
m=scanner.nextInt();
a=new char[n][m];
book=new boolean[n][m];
scanner.nextLine();
for(int i=0;i<n;i++){
String tmp=scanner.nextLine();
for(int j=0;j<m;j++){
a[i][j]=tmp.charAt(j);
}
}
Node node=new Node(-1,-1,-1);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(a[i][j]=='S'){
node=new Node(i,j,5);
}
}
}
Queue<Node> queue=new LinkedList<>();
queue.add(node);
book[node.x][node.y]=true;
int path=0;
while (!queue.isEmpty()){
int size=queue.size();
while (size--!=0){
Node tmp=queue.poll();
if (a[tmp.x][tmp.y]=='E') {
System.out.println(path);
return;
}
for(int k=0;k<4;k++){
int x=tmp.x+visitX[k];
int y=tmp.y+visitY[k];
if(check(x,y)){
Node cur=new Node(x,y,tmp.flyCount);
queue.add(cur);
book[x][y]=true;
}
}
if(tmp.flyCount>0){//飛躍
int x=n-1-tmp.x;//這裏!-纔對。
int y=m-1-tmp.y;
if(check(x,y)){
Node cur=new Node(x,y,tmp.flyCount-1);
queue.add(cur);
book[x][y]=true;
}
}
}
path++;
}
System.out.println(-1);
}
public static boolean check(int i,int j){
if(i<0||i>=n||j<0||j>=m||book[i][j]||a[i][j]=='#') return false;
return true;
}
}
只是測了樣例可以過,不知提交系統能不能ac