阿里2020.3.23暑期实习笔试

答案借鉴:https://www.nowcoder.com/discuss/389778?type=1

1.一共有n个人,从中选一批人出来组队,再从组队的人中选一个人作为队长,一共有多少种选法。
举例:
输入:2
输出:4
过程:{\(\dot{x_1}\)},{\(\dot{x_2}\)},{\(\dot{x_1}\),\(x_2\)},{\(x_1\),\(\dot{x_2}\)}

解:这个题我用组合做的,即\(=\sum{C_n^i*i}\)
组合的代码:

    public static long combination(int m, long n) {
        if (m == n)
            return 1;
        if (m == 0)
            return 1;
        return combination(m, n - 1) + combination(m - 1, n - 1);
    }

但很明显……这种这么硬核的计算方法超时不能用。
然后在牛客上看到别人的分析。

动态规划解法:已知n个人的取法为dp[n]。当求n+1人取法dp[n+1]时,新添加的第n+1人有可取可不取两种状态,但是不当队长,因此这时就有2*dp[n]种方法。然后令第n+1人为队长,剩下的人就有\(2^n\)种取法。可的转移方程状态dp[n+1] = 2*dp[n] + \(2^n\)

但神奇的是就算找到了这种方法,也ac不了,非要用快速幂去计算\(2^n\)。可以是都是坑了。

    public static long countTeamer(long n) {
        if (n == 0)
            return 0;
        long count = 0;
        long m = 1000000000 + 7;
        count = n * binaryPow(2, n - 1, m);
        return count;
    }

    //这里的递归可以考虑用dp做,毕竟递归也是很耗时的
    public static long binaryPow(long a, long n, long m) {
        long temp;
        if (n == 0)
            return 1;
        else if (n % 2 == 1) {
            temp = a * binaryPow(a, n - 1, m) % m;
        } else {
            temp = binaryPow(a, n / 2, m);
            temp = temp * temp % m;
        }
        return temp;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            long n = sc.nextLong();
            long count = countTeamer(n);
            System.out.print(count);
        }
    }

2.有一组n*m的格子,格子中为‘.’的可通行,为‘#’的为障碍物,为‘S’的是开始点,为‘E’的是结束点,计算从开始到结束最短路径长。
每次只可上下左右一格前进,或使用飞行棋。飞行棋是可以跳跃到当前位置对称位置,即\(x+x'=m-1,y+y'=n-1\).飞行棋最多使用5次。
A:
我自己是用DFS做的,上面引用的答案借鉴区的答案是用BFS做的。图方便我把所有结果都放到array里面再找最小。
但找最小路径的题最好还是BFS做吧。
答案仅参考,而且我怀疑会超时……

    public static int minPath(char[][] c, int line, int col) {
        ArrayList<Integer> array = new ArrayList<>();
        if (c == null || c.length == 0 || c[0].length
                == 0)
            return -1;
        int min = Integer.MAX_VALUE;
        int count = 0;
        for (int i = 0; i < line; i++) {
            for (int j = 0; j < col; j++) {
                if (c[i][j] == 'S') {
                    dfs(c, count, i, j, array, 5);
                    break;
                }
            }
        }
        for (Integer i : array) {
            min = Math.min(min, i);
        }
        return min;
    }

    private static void dfs(char[][] c, int count, int line, int col, ArrayList<Integer> array, int fx) {
        if (c[line][col] == 'E') {
            array.add(count);
            return;
        }
        if (line != 0 && c[line - 1][col] != '#') {
            c[line][col] = '#';
            dfs(c, count + 1, line - 1, col, array, fx);
            c[line][col] = '.';
        }
        if (line != c.length - 1 && c[line + 1][col] != '#') {
            c[line][col] = '#';
            dfs(c, count + 1, line + 1, col, array, fx);
            c[line][col] = '.';
        }
        if (col != 0 && c[line][col - 1] != '#') {
            c[line][col] = '#';
            dfs(c, count + 1, line, col - 1, array, fx);
            c[line][col] = '.';
        }
        if (col != c.length - 1 && c[line][col + 1] != '#') {
            c[line][col] = '#';
            dfs(c, count + 1, line, col + 1, array, fx);
            c[line][col] = '.';
        }
        if (fx > 0 && c[c.length - 1 - line][c[0].length - 1 - col] != '#') {
            c[line][col] = '#';
            dfs(c, count + 1, c.length - 1 - line, c[0].length - 1 - col, array, fx - 1);
            c[line][col] = '.';
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int line = sc.nextInt();
        int col = sc.nextInt();
        char[][] c = new char[line][col];
        for (int i = 0; i < line; i++) {
            String s = sc.next();
            for (int j = 0; j < line; j++) {
                c[i][j] = s.charAt(j);
            }
        }
        sc.close();
//        int line = 4;
//        int col = 4;
//        char[][] c = new char[][]{{'#', 'S', '.', '.'},
//                {'E', '#', '.', '.'}, {'.', '.', '.', '.'}, {'.', '.', '.', '.'}};
        int minPath = minPath(c, line, col);
        System.out.print(minPath);
    }
posted @ 2020-03-23 22:12  Shaw_喆宇  阅读(494)  评论(0编辑  收藏  举报