Seeker的奇妙求职历险(滴滴笔试和米哈游笔试)

A+B

假设a,b,c为0到9之间的数,且a!=0,给出一个整数,求有多少对abc+acc的和等于这个整数。

输入
1068
输出 第一行为组合数,后面每一行为一个组合
1
524 544

分析:
暴力枚举,一开始的时候没看到每一行为一个组合,以为在一行里面把所有组合全输出,结果也能过60+,不知道这个测试用例怎么设计的。改成每行一个就过了。

public static void main(String[] args) {
     
    Scanner scanner = new Scanner(System.in);
    int n = scanner.nextInt();
    List<int[]> res = new ArrayList<>();
    for(int a=1;a<10;a++){
     
        for(int b=0;b<10;b++){
     
            for(int c=0;c<10;c++){
     
                if(a == b)
                    continue;
                if(b == c)
                    continue;
                if(c == a)
                    continue;
                int num1 = a*100+b*10+c;
                int num2 = a*100+c*10+c;
                if(num1 + num2 == n)
                    res.add(new int[]{
     num1,num2});
            }
        }
    }
    System.out.println(res.size());
    for(int i=0;i<res.size()-1;i++){
     
        int[] tmp = res.get(0);
        System.out.println(tmp[0]+" "+tmp[1]);
    }
    int[] tmp = res.get(res.size()-1);
    System.out.print(tmp[0]+" "+tmp[1]);
}

斐波那契蛇

给出一个NN的矩阵,坐标为(0,0)的点为第NN个斐波那契数,依次从外圈向内圈递进。

输入 一个整数为n
3
输出 斐波那契蛇
34 21 13
1 1 8
2 3 5

分析:矩阵报数+斐波那契数。

public static void main(String[] args) {
     
    Scanner scanner = new Scanner(System.in);
    int n = scanner.nextInt();
    if(n == 0){
     
        System.out.print("\n");
        return;
    }
    if(n == 1){
     
        System.out.println("1");
        return;
    }
    long[] dp = new long[n*n];
    dp[0] = 1;
    dp[1] = 1;
    for(int i=2;i<n*n;i++)
        dp[i] = dp[i-1]+dp[i-2];
    long[][] matrix = new long[n][n];
    int left = 0;
    int right = n-1;
    int up = 0;
    int down = n-1;
    int index = n*n-1;
    while(true){
     
        for(int i=left;i<=right;i++)
            matrix[up][i] = dp[index--];
        up++;
        if(up > down)
            break;
        for(int i=up;i<=down;i++)
            matrix[i][right] = dp[index--];
        right--;
        if(left > right)
            break;;
        for(int i = right;i>=left;i--)
            matrix[down][i] = dp[index--];
        down--;
        if(up > down)
            break;
        for(int i=down;i>=up;i--)
            matrix[i][left] = dp[index--];
        left++;
        if(left > right)
            break;
    }
    for(int i=0;i<n;i++){
     
        for(int j=0;j<n;j++){
     
            System.out.print(matrix[i][j]);
            if(j!=n-1)
                System.out.print(" ");
        }
        if(i!=n-1)
            System.out.print("\n");
    }
}

分数的四则运算

实现两个分数的四则运算。

输入 一行由空格隔开
1/8 + 3/8
输出
1/2 分数的最简形式,符合书写习惯。

分析:利用辗转相除法求出最大公约数来进行约分。java里面好像没有api可以直接求最大公约数,所以自己实现了一个,看大佬的好像py里面有math.gcd
由于时间紧迫,写复杂了,加减的时候先直接相乘再约分就好了,我这边先求最小公倍数再约分,多此一举。
再考虑一下分子为0,分母为1以及负数的情况,测试用例比较简单,最后AC了。不过代码写的有点长,应该还可以精简一下。

public static void main(String[] args) {
     
    Scanner scanner = new Scanner(System.in);
    String tmp = scanner.nextLine();
    String[] strings = tmp.split(" ");
    int[] num1 = new int[2];
    int[] num2 = new int[2];
    char op;
    String[] num = strings[0].split("/");
    num1[0] = Integer.valueOf(num[0]);
    num1[1] = Integer.valueOf(num[1]);
    op = strings[1].toCharArray()[0];
    num = strings[2].split("/");
    num2[0] = Integer.valueOf(num[0]);
    num2[1] = Integer.valueOf(num[1]);
    int[] res = new int[2];
    if(op == '+')
        res = and(num1,num2);
    if(op == '-')
        res = sub(num1,num2);
    if(op == '*')
        res = mti(num1,num2);
    if(op == '/')
        res = chu(num1,num2);
    if(res[0] == 0)
        System.out.println("0");
    else if(res[1] == 1)
        System.out.println(res[0]);
    else
        System.out.println(res[0]+"/"+res[1]);
}
public static int[] and(int[] num1,int[] num2){
     
    int g = gcd(num1[1],num2[1]);
    int tmp1 = num1[1]/g;
    int tmp2 = num2[1]/g;
    num1[0] *= tmp2;
    num1[1] *= tmp2;
    num2[0] *= tmp1;
    num2[1] *= tmp1;
    int[] res = new int[2];
    res[0] = num1[0] + num2[0];
    res[1] = num1[1];
    if(res[0] == 0)
        return new int[]{
     0,0};
    boolean flag = false;
    if(res[0] < 0)
        flag = true;
    if(flag)
        g = gcd(-res[0],res[1]);
    else
        g = gcd(res[0],res[1]);
    res[0] /= g;
    res[1] /= g;
    return res;
}
public static int[] sub(int[] num1,int[] num2){
     
    boolean flag = false;
    int g = gcd(num1[1],num2[1]);
    int tmp1 = num1[1]/g;
    int tmp2 = num2[1]/g;
    num1[0] *= tmp2;
    num1[1] *= tmp2;
    num2[0] *= tmp1;
    num2[1] *= tmp1;
    int[] res = new int[2];
    res[0] = num1[0] - num2[0];
    res[1] = num1[1];
    if(res[0] == 0)
        return new int[]{
     0,0};
    if(res[0] < 0)
        flag = true;
    if(flag)
        g = gcd(-res[0],res[1]);
    else
        g = gcd(res[0],res[1]);
    res[0] /= g;
    res[1] /= g;
    return res;
}
public static int[] mti(int[] num1,int[] num2){
     
    int[] res = new int[2];
    res[0] = num1[0]*num2[0];
    res[1] = num1[1]*num2[1];
    if(res[0] == 0)
        return new int[]{
     0,0};
    int g = 0;
    boolean flag = false;
    if(res[0] < 0)
        flag = true;
    if(flag)
        g = gcd(-res[0],res[1]);
    else
        g = gcd(res[0],res[1]);
    res[0] /= g;
    res[1] /= g;
    return res;
}
public static int[] chu(int[] num1,int[] num2){
     
    int[] res = new int[2];
    res[0] = num1[0]*num2[1];
    res[1] = num1[1]*num2[0];
    if(res[0] == 0)
        return new int[]{
     0,0};
    boolean flag = false;
    int g = 0;
    if(res[0] < 0)
        flag = true;
    if(flag)
        g = gcd(-res[0],res[1]);
    else
        g = gcd(res[0],res[1]);
    res[0] /= g;
    res[1] /= g;
    return res;
}
public static int gcd(int a,int b){
     
    if(a<b){
     
        int c = a;
        a = b;
        b = c;

    }
    int r = a%b;
    while(r!=0){
     
        a = b;
        b = r;
        r = a%b;
    }
    return b;
}

能否组成矩阵

给出一个M*N的矩阵,矩阵里面只有1和0。求从矩阵中取出若干行,能否组成一个每列有且仅有一个1的新矩阵,若能返回YES,否则返回NO。

输入
2 3
0 1 0
0 0 1
输出
NO
输入
4 4
0 0 0 1
1 0 0 0
1 1 1 0
0 0 0 0
YES 第一行和第三行组成的矩阵能够满足条件。

分析:自己写的暴力算法,枚举出所有行的组合并且组成一个矩阵判断是否合法,由于时间复杂度太高,过了88之后显示超时了。
后来想剪一下枝,优化一下代码,把矩阵的状态往下传而非每次都新建矩阵,但是一直无法AC,过得用例还越来越少,最后只能先去做问答题,然而问答题难得一比,根本不会做

后来看到牛客大佬的思路,排列组合出所有的可能,然后看是否能够刚好组成一个2^m-1的数。

    static boolean res;
    static boolean[] visited;
    public static void main(String[] args) {
     
        Scanner scan = new Scanner(System.in);
        int m = scan.nextInt();
        int n = scan.nextInt();
        res = false;
        visited = new boolean[m];
        int[][] matrix = new int[m][n];
        for(int i=0;i<m;i++){
     
            for(int j=0;j<n;j++)
                matrix[i][j] = scan.nextInt();
        }
        List<Integer> path = new ArrayList<>();
        int[] one = new int[matrix[0].length];
        backtrace(path,matrix);
        if(res)
            System.out.println("YES");
        else
            System.out.println("NO");
    }
    public  static void backtrace(List<Integer> path,int[][] matrix){
     
        if(res)
            return;
        for(int i=0;i<matrix.length;i++){
     
            if(visited[i])
                continue;
            path.add(i);
            visited[i] = true;
            if(check(buildMatrix(path,matrix))){
     
                res = true;
                return;
            }
            backtrace(path,matrix);
            path.remove(path.size()-1);
            visited[i] = false;
        }
    }
    public static int[][] buildMatrix(List<Integer> path,int[][] matrix){
     
        int[][] tmp = new int[path.size()][matrix[0].length];
        for(int i=0;i<path.size();i++){
     
            tmp[i] = matrix[path.get(i)];
        }
        return tmp;
    }
    public  static boolean check(int[][] matrix){
     
        int[] flag = new int[matrix[0].length];
        int count = 0;
        for(int j=0;j<flag.length;j++){
     
            for(int i=0;i<matrix.length;i++){
     
                if (matrix[i][j] == 1){
     
                    if(flag[j] > 0)
                        return false;
                    flag[j]++;
                    count++;
                }

            }
        }
        return count == matrix[0].length;
    }
//牛客大佬@爱玩矢量 的代码,看来大佬是个魔禁厨
def second():
    n, m = map(int, input().split(' '))
    matrix = []
    for _ in range(n):
        matrix.append(eval('0b' + ''.join(input().split(' '))))

    from itertools import combinations
    target = 2 ** m - 1
    for i in range(1, n + 1):
        for c in combinations(matrix, i):
            if sum(c) == target:
                print('YES')
                break
        else:
            continue
        break
    else:
        print('NO')

后记

现在是22日下午15点02分,昨天晚上做了两场笔试,还好滴滴的比较简单,做完才8点10分,还赶得上米哈游的。有一说一,米哈游的笔试比滴滴难上不少,第一题就写了很久,第二题最后也没能AC。
马上4点钟有美团的笔试,希望这次也能运气不错地多A几题,不过听华子说上次美团笔试很难。
有道这边约了下周一早上面试,感觉像是备胎陪跑的感觉,过的希望应该不大,雷火这边下周一下午hr面,希望能给个意向书吧,球球了。

最后,老司机这个逼天天催我,看着师姐每天被PUA,我感觉下一个可能就是我了,哎,研究生太难了,希望能再拿一到两个意向书,加油。


Seeker的奇妙求职历险(滴滴笔试和米哈游笔试)_第1张图片

你可能感兴趣的:(Seeker的奇妙求职历险)