用友Java后端笔试2023-8-5

计算被直线划分区域

在笛卡尔坐标系,存在区域[A,B],被不同线划分成多块小的区域,简单起见,假设这些不同线都直线并且不存在三条直线相交于一点的情况。

img

那么,如何快速计算某个时刻,在 X 坐标轴上[ A, B] 区间面积被直线划分成多少块?

A轴平行坐标Y轴,A (x=1)

B轴平行坐标Y轴, B(x = 20);

输入描述

输入采用多行输入,一行4个数据,分别表示两个坐标点,一行一条直线;

1,4,20,100 - 表两个点,点t1的坐标为(1,4),点t2坐标为(20,100)

输出描述

输出为整数,表示被输入线段划分的面积个数

示例1

输入

1,37,20,4
1,7,20,121

输出

4

备注

AB之间的线段不平行于Y轴

思路

几何题,当两条线在这一区域内不相交时,区域空间增加1,当两条线的交点在这一区域内时,空间增加2,所以我们判断交点是否在区域内即可

代码

java 复制代码
 public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        List<int[]> edges = new ArrayList<>();
        int res = 1;

        while(in.hasNextLine()){
            String inputLine = in.nextLine();
            if (inputLine.isEmpty()) {
                break; // 如果输入为空行,退出循环
            }

            res+=1;
            String[] line = inputLine.split(",");
            if(line[0]=="") continue;

            int[] nodes = new int[4];
            for(int i=0;i<4;i++){
                nodes[i] = Integer.parseInt(line[i]);
            }
            for(int[] edge:edges){
                double x = getIntersection(nodes[0],nodes[1],nodes[2],nodes[3],edge[0],edge[1],edge[2],edge[3]);
                if(x<20 && x>1) res+=1;
            }
            edges.add(nodes);

        }

        System.out.println(res);
    }

    static double getIntersection(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){
        double k1 = (y1-y2)/(x1-x2);
        double b1 = y1 - k1*x1;
        double k2 = (y4-y3)/(x4-x3);
        double b2 = y3 - k2*x3;
        double x = (b2-b1)/(k1-k2);
        return x;
    }

最佳面试策略

小明最近在找工作,收到了许多面试邀约,可参加的面试由interviews 数组表示,其中 interviews[i] = [startTimei, endTimei, possibilityi],表示第 i 个面试在 startTimei 开始,endTimei 结束,面试成功的可能性是 possibilityi,该值越大,通过面试的可能性越大,由于精力限制,小明最多可以参加 k 场面试。

小明同一时间只能参加一场面试,如果要参加某场面试,必须完整参加这场面试才可能通过面试,即不能同时参加一个开始时间和另一个结束时间相同的两场面试。

请给出小明面试成功可能性的最大和。

示例1

输入

[[1,2,3],[3,4,2],[2,4,4]],2

输出

5

说明

小明参加 [1, 2, 3], [3, 4, 2] 两场面试,面试通过可能性的和为 3 + 2 = 5

示例2

输入

[[1,2,3],[3,4,2],[2,4,6]],2

输出

6

说明

只参加面试 [2, 4, 6],面试通过的可能性的和最大,为 6 

思路

对于这道题,我们先定义dp的状态,dp[i][j]为面对i这个时间段的面试,已经面试了j次,决策后的最大可能值

先对interviews根据左端的值进行排序。

然后从后往前遍历interviews,使用二分搜索的方法算出当前面试i的下一场面试,然后我们逐次消耗面试次数,记录消耗j次面试机会的最大可能值,与进行下一次面试的值做比较,得到最终的最大值

注意,这里我们记录了dp[i+1][j]的值,就是当这个可能值 > i加上后面的面试的可能值时,会保留更大的那个可能值的结果

代码

java 复制代码
import java.util.Arrays;

public class algorithm {
    public static void main(String[] args) {
        int[][] s = { {1,2,3},{3,4,2},{2,4,6} };
        System.out.println(maxValue(s,2));

    }

    public static int maxValue(int[][] interviews,int k){
        Arrays.sort(interviews,(a,b)->a[0]-b[0]);

        int n = interviews.length;
        int[][] dp = new int[n+1][k+1];
        for(int i=n-1;i>=0;i--){
            int l=i,r=n;
            while (l<r){
                int mid = (l+r)>>1;
                if(interviews[i][1]<interviews[mid][0]) r=mid;
                else l=mid+1;
            }
            for(int j=0;j<=k;j++){
                dp[i][j] = dp[i+1][j];
                if(j>0) dp[i][j] = Math.max(dp[i][j],dp[r][j-1]+interviews[i][2]);
            }
        }

        return dp[0][k];
    }
    
}

星球间的最短通路

在一个遥远的银河中,有N个星球(编号从1到N),这些星球之间通过星际门进行连接。每个星际门都连接两个星球,并且可以双向通行。

每个星际门的开启需要消耗一定的能量,这个能量由星际门上的数字表示。每个星际门上的数字都是唯一的。

现在,由于某种原因,所有的星际门都处于关闭状态。作为一个探索者,你的任务是找出一种方式,开启最少的星际门,使得所有的星球都至少通过一个开启的星际门与其他星球连接。

给你一些可连接的选项 connections,其中 connections[i] = [Xi, Yi, Mi] 表示星球 Xi 和星球 Yi 之间可以开启一个星际门,并消耗 Mi 能量。

计算联通所有星球所需的最小能量消耗。如果无法联通所有星球,则输出-1。

示例1

输入

3,[[1, 2, 5], [1, 3, 6], [2, 3, 1]]

输出

6

备注

1 ≤ N ≤ 100

思路

使用克鲁斯卡尔算法求最小图,这其中使用到了并查集的东西

代码

java 复制代码
import java.util.Arrays;

public class Main {

    int[] fa;

    void init(int n){
        fa = new int[n];
        for(int i=0;i<n;i++) fa[i] = i;
    }

    int find(int x){
        return x == fa[x]? x: (fa[x] = find(fa[x] ));
    }

    void union(int x,int y){
        fa[find(x)] = find(y);
    }

    public int minimumCost(int n,int[][] connections){
        init(20000);
        Arrays.sort(connections,(a,b)->a[2]-b[2]);
        int ans = 0;
        for(int[] arr:connections){
            int a = arr[0],b=arr[1],w=arr[2];
            if(find(a)!=find(b)){
                union(a,b);
                ans+=w;

            }
        }

        return ans;

    }


    public static void main(String[] args) {
        Main a = new Main();
        int[][] s = {
                {1, 2, 5}, {1, 3, 6}, {2, 3, 1}
        };

        System.out.println(a.minimumCost(3,s))
        ;


    }
}
相关推荐
penguin_bark2 分钟前
69. x 的平方根
算法
这可就有点麻烦了12 分钟前
强化学习笔记之【TD3算法】
linux·笔记·算法·机器学习
救救孩子把13 分钟前
深入理解 Java 对象的内存布局
java
落落落sss15 分钟前
MybatisPlus
android·java·开发语言·spring·tomcat·rabbitmq·mybatis
苏宸啊18 分钟前
顺序表及其代码实现
数据结构·算法
万物皆字节21 分钟前
maven指定模块快速打包idea插件Quick Maven Package
java
lin zaixi()21 分钟前
贪心思想之——最大子段和问题
数据结构·算法
FindYou.22 分钟前
C - Separated Lunch
算法·深度优先
夜雨翦春韭28 分钟前
【代码随想录Day30】贪心算法Part04
java·数据结构·算法·leetcode·贪心算法
我行我素,向往自由34 分钟前
速成java记录(上)
java·速成