一共两个题。笔试时先通读了两个题的题目。因为第二题有思路觉得简单就先写的第二题。结果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