阿里秋招笔试两道编程题(2021-08-18)

恭喜发现宝藏!微信搜索公众号【TechGuide】实时互联网大厂笔经面经闪电速递!
作者@TechGuide【全网同名】
点赞再看,养成习惯,您动动手指对原创作者意义非凡🤝

番哥提示

  1. 阿里的题也是会和高中的数学知识相结合,有些比较巧妙。
  2. 一小时两题,很考验一次通过率。

第一道:求缺失正方形顶点(100%)

题目描述

找到非对角点的那一个点,设为(x0, y0), 另外两个对角点为(x1, y1), (x2, y2),求 (x, y);

思路解析

向量法:
先找3个点的交点,记为a, 剩余两个点为b,c,问题为求d。 向量法: 由 ad = ab + ac 可接解出 d = ab + ac + a

参考代码:

Java版本

public static int[] pair(int x1, int y1, int x2, int y2, int x3, int y3) {
        int[] arr = new int[2];
        if ((x1 - x2) * (x1 - x3) + (y1 - y2) * (y1 - y3) == 0) {
            arr[0] = x2 + x3 - x1;
            arr[1] = y2 + y3 - y1;
            return arr;
        }
        if ((x2 - x1) * (x2 - x3) + (y2 - y1) * (y2 - y3) == 0) {
            arr[0] = x1 + x3 - x2;
            arr[1] = y1 + y3 - y2;
            return arr;
        }
        if ((x3 - x1) * (x3 - x2) + (y3 - y1) * (y3 - y2) == 0) {
            arr[0] = x1 + x2 - x3;
            arr[1] = y1 + y2 - y3;
            return arr;
        }
        return arr;
    }

Python版本

arr = [[-1,1],[0,0],[0,1]]
idx = [[0,1,2],[1,0,2],[2,0,1]]
for a, b, c in idx:
    ab = [ arr[b][0] - arr[a][0], arr[b][1] - arr[a][1]] 
    ac = [ arr[c][0] - arr[a][0], arr[c][1] - arr[a][1]] 
    res = sum([x * y for x, y in zip(ab, ac)])
    if res == 0:
        res = [x + y for x, y in zip(ab, ac)]
        res = [res[0] + arr[a][0], res[1] + arr[a][1]]
        print('%d %d' % (res[0], res[1]))
        break

第二道: 图(题目待补充,可以尝试理解思路,两种算法实现供参考)

思路解析

回溯法:
数据处理, 将人工通道和天然通道合并为代码中的 channels, 不可达的点专门用数组表示,问题就变得简单了
使用used数组表示,是否之前到达过该点,如果到达过,则返回;

示例:

6 2 2 0
9 1 6 3 6
2 5 1
3 6 2
1 5 3
6 5 9

参考代码

Java版本

public class Solution2 {
    private static int rst = Integer.MAX_VALUE;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        for (int i = 0; i < 1; i++) {
            int n = sc.nextInt(), m = sc.nextInt(), k = sc.nextInt(), p = sc.nextInt();
            sc.nextLine();
            int[] costs = new int[n - 1];
            for (int j = 0; j < n - 1; j++) {
                costs[j] = sc.nextInt();
            }
            sc.nextLine();
            int[][] channels = new int[m * 2 + k][3];
            int[][] arts = new int[m][3];
            int j = 0;
            for (; j < m * 2 + k ;j += 2) {
                channels[j][0] = sc.nextInt();
                channels[j][1] = sc.nextInt();
                channels[j][2] = sc.nextInt();
                channels[j + 1][0] = channels[j][1];
                channels[j + 1][1] = channels[j][0];
                channels[j + 1][2] = channels[j][2];
                sc.nextLine();
            }
            int[][] nature = new int[k][3];
            for (; j < m * 2 + k; j++) {
                nature[j][0] = sc.nextInt();
                nature[j][1] = sc.nextInt();
                nature[j][2] = sc.nextInt();
                sc.nextLine();
            }
            int[] cannot = new int[n];
            for (int x = 0; x < p; x++) {
                cannot[sc.nextInt() - 1] = -1;
            }

            int[] used = new int[n];   // 是否已经达到过该点
            for (int x = 0; x < channels.length; x++) {
                System.out.println(Arrays.toString(channels[x]));
            }
            System.out.println("cannot = " + Arrays.toString(cannot));
            handle(costs, channels, cannot, n, used, 1, 0);
            System.out.println(rst == Integer.MAX_VALUE ? -1 : rst);
            rst = Integer.MAX_VALUE;
        }
    }

    private static void handle(int[] costs, int[][] channels, int[] cannot, int n, int[] used, int next, int total) {
        if (used[next - 1] == 1 || cannot[next - 1] == -1)
            return;
        if (next == n) {
            rst = Math.min(rst, total);
            return;
        }
        used[next - 1] = 1;
        handle(costs, channels, cannot, n, used, next + 1, total + costs[next - 1]);
        used[next - 1] = 0;
        for (int i = 0; i < channels.length; i++) {
            if(channels[i][0] == next){
                used[next - 1] = 1;
                handle(costs, channels, cannot, n, used, channels[i][1], total + channels[i][2]);
                used[next - 1] = 0;
            }
        }
    }
}

迪杰斯特拉算法:

private static void Dijkstra(long[][] map, int n) {
        boolean[] vis = new boolean[n+1];
        long[] dis = new long[n+1];
        for (int i = 1; i <= n; i++) {
            dis[i] = Integer.MAX_VALUE;
        }
        dis[1] = 0;
        for (int i = 0; i < n; i++) {
            int temp = -1;
            for (int j = 1; j <= n; j++) {
                if (!vis[j] && (temp == -1 || dis[temp] > dis[j])) {
                    temp = j;
                }
            }
            vis[temp] = true;
            for (int j = 1; j <= n; j++) {
                if (map[temp][j] != Integer.MAX_VALUE) {
                    dis[j] = Math.min(dis[j], dis[temp] + map[temp][j]);
                }
            }
        }
        if (dis[n] == Integer.MAX_VALUE) {
            System.out.println(-1);
        } else {
            System.out.println(dis[n]);
        }
    }

恭喜发现宝藏!微信搜索公众号【TechGuide】关注更多新鲜好文和互联网大厂的笔经面经。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值