记阿里笔试2020.3.23惨痛经历

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

发布了184 篇原创文章 · 获赞 60 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/StubbornAccepted/article/details/80869924