阿里3.23笔试,笔试被虐惨了,借鉴别人写的代码,供大家参考

题目

1、从n个人中选择任意数量的人员组成一支队伍,然后从一支队伍中选出一位队长,不同的队长算不同的组合,问这样的组合的数量对10^9+7取模 。

数据范围:1 <= n <= 1000000000;

示例

输入:n = 2
输出:4
解释,(1),(2)(1,2),(2,1)四种,括号第一个为队长

思路:

首先一看数据范围,应该要O(logN)级别的方法才能AC,分析问题首先应该是个排列组合问题,得到通项公式为:
$$
思路1:可以暴力算,当然不推荐,算了也是白算

思路2:动态规划,没写出来,而且也达不到O(logN)复杂度

思路3:数学知识告诉我们,res的通项公式为:
$$
要求2^n - 1,O(logN)复杂度,经典的快速幂算法。

小知识:介绍一个解决找规律问题的好网站OEIS( 在线整数数列查询网站 http://oeis.org/ ),笔试的时候手机被锁了,没想到用电脑去查一查,好气

import java.util.Scanner;

public class Main {
    static int mod = 1000000007;

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        System.out.println((pow(n - 1) * n) % mod);
    }

    public static long pow(int n) {
        if (n == 0)
            return 1;
        long half = pow(n / 2);
        if (n % 2 == 0)
            return (half * half) % mod;
        else
            return (half * half * 2) % mod;
    }
}

2、 一个地图n*m,包含1个起点,1个终点,其他点包括可达点和不可达点。 每一次可以:上下左右移动,或使用1点能量从(i,j)瞬间移动到(n-1-i, m-1-j),最多可以使用5点能量。

数据范围:2 <= n,m <= 500;

示例

输入:
4 4
#S..
E#..
....
....
输出:4
解释:S(0,1)先瞬移到(3, 2),然后往上一步,往右一步,瞬移到E,一共4步

思路:

如果没有瞬移步数要求,那这就是一个经典的地图问题,算是BFS的模板题,那加入瞬移步数要求之后,需要记录fly变量,fly表示已经瞬移的步数。

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
    static int [] dx = {1, -1, 0 ,0};
    static int [] dy = {0, 0, 1, -1};
    static int n;
    static int m;
    static int endX;
    static int endY;
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        n = input.nextInt();
        m = input.nextInt();
        char[][] map = new char[n][m];
        Queue<Pair> queue = new LinkedList<Pair>();
        for (int i = 0;i < n;i++) {
            map[i] = input.next().toCharArray();
            for (int j = 0;j < map[i].length;j++) {
                if (map[i][j] == 'S') {
                    Pair pair = new Pair(i, j);
                    queue.add(pair);
                } else if (map[i][j] == 'E') {
                    endX = i;
                    endY = j;
                }
            }
        }
        System.out.println(BFS(map, queue));
    }
    public static boolean check(int x,int y) {
        if (x >= 0 && x < n && y >= 0 && y < m)
            return true;
        return false;
    }
    public static int BFS(char[][] map, Queue<Pair> queue) {
        while (!queue.isEmpty()) {
            int size = queue.size();
            while (size-- > 0) {
                Pair top = queue.poll();
                if (top.x == endX && top.y == endY)
                    return top.step;
                for (int i = 0;i < 4;i++) {
                    int curX = top.x + dx[i];
                    int curY = top.y + dy[i];
                    Pair nextPair = new Pair(curX, curY);
                    nextPair.step = top.step + 1;
                    nextPair.fly = top.fly;
                    if (check(curX, curY) && (map[curX][curY] == '.' || map[curX][curY] == 'E')) {
                        queue.add(nextPair);
                        map[curX][curY] = 'X';
                    }
                }
                int flyX = n - 1 - top.x;
                int flyY = m - 1 - top.y;
                if (check(flyX, flyY) && top.fly < 5 && (map[flyX][flyY] == '.' || map[flyX][flyY] == 'E')) {
                    Pair pair = new Pair(flyX, flyY);
                    pair.step = top.step + 1;
                    pair.fly = top.fly + 1;
                    queue.add(pair);
                    map[flyX][flyY] = 'X';
                }
            }
        }
        return -1;
    }
}
class Pair {
    int x;
    int y;
    int step;
    int fly;
    public Pair(int x,int y) {
        // TODO Auto-generated constructor stub
        this.x = x;
        this.y = y;
    }
}
#阿里实习生笔试##阿里巴巴##笔试题目#
全部评论
第一题是不是可以这样理解n个队长轮换,剩下的n-1个人要么选要么不选,就是n*2^(n-1)
13 回复
分享
发布于 2020-03-24 20:03
 🤣居然还有找规律的网站,感谢,网站收藏了
2 回复
分享
发布于 2020-03-23 23:24
百信银行
校招火热招聘中
官网直投
 笔试被虐惨了,发个代码总结一下吧,大家可以探讨探讨,第二题的代码是借鉴一位c++老哥的代码
1 回复
分享
发布于 2020-03-23 22:04
动态规划解法:已知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。代码: int get_num(int n){ int k = 1; for(int i = 1; i<n; ++i){ int temp = k*2 + pow(2,i); k = temp%(1000000007); } return k; } 答案没错,就是0%,崩溃🙃
点赞 回复
分享
发布于 2020-03-23 23:52
请问楼主第二问ac了吗
点赞 回复
分享
发布于 2020-03-24 04:39
第二题没有记录访问过的点,不是有的点会一直重复访问?
点赞 回复
分享
发布于 2020-03-24 08:45
还好我参加的是3.20号的
点赞 回复
分享
发布于 2020-03-24 11:39
楼主像第一题如何用这个网站找规律呀?
点赞 回复
分享
发布于 2020-03-24 13:14
  #春招# 阿里巴巴企业智能,大有可为,欢迎加入
点赞 回复
分享
发布于 2020-03-24 13:27
请问笔试过程中可以跳出去百度嘛,在那个网站上查这个数列算不算作弊
点赞 回复
分享
发布于 2020-03-24 16:12
第二题BFS会超时吗?
点赞 回复
分享
发布于 2020-03-24 20:39
第2题,题目补充:"#" 表示不可达点,"."表示可达点;
点赞 回复
分享
发布于 2020-03-25 14:36
学习学妹们,阿里新零售CCO技术部面试机会很多的,笔试成绩你懂的哈,速来
点赞 回复
分享
发布于 2020-03-25 14:48
第一题 我觉得 主要就是看 怎么优化2^(n-1) % mod 这里其实还可以进行进一步划分将 2^(n-1) 进行拆解优化   dp状态为 余数 long long dp(long long n){     int mod=1000000007;     if (n == 0){ return 0;}     long long a = 1;     for(int i=0;i<n-1;i++){         a = a % mod;         a = a + a;           }     long long result = ((n % mod) * (a % mod) % mod);     return result; }
点赞 回复
分享
发布于 2020-03-25 18:24
楼主,我对第二题有点疑问,没有fly数量要求的话,每次找到X,Y,然后设为”X“我觉得是可以的,但是fly数量是有限的,在这种情况下,假如有的pair先用光了fly的次数,到达了某个点,然后再移动可能就变慢了,而有的pair虽然到达这个点的时间久了一些,但还留有fly次数,可能一到这个点, 一次fly就成功了,此时把前面那种情况吧这个点设为”X“是不是就会有影响啊
点赞 回复
分享
发布于 2020-03-28 10:48
通项公式怎么算出来的😫
点赞 回复
分享
发布于 2020-03-29 17:26
    int n;     cin>>n;          //先选择一个队长     int res=n;    //选择队长后,剩下n-1个人,子集为2的(n-1)次方     for(int i=1;i<=n-1;i++)     {         res = res*2%(1000000000+7);     }     cout<<res; 时间复杂度O(n)
点赞 回复
分享
发布于 2020-04-22 14:17

相关推荐

16 93 评论
分享
牛客网
牛客企业服务