华为OD机试 2024C卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷+C卷)》。
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
疫情期间需要大家保证一定的社交距离,公司组织开交流会议。
座位一排共 N 个座位,编号分别为 [0, N - 1] , 要求员工一个接着一个进入会议室,并且可以在任何时候离开会议室。
满足:
- 每当一个员工进入时,需要坐到最大社交距离(最大化自己和其他人的距离的座位);
- 如果有多个这样的座位,则坐到 索引最小 的那个座位。
二、输入描述
- 会议室座位总数 seatNum 。(1 <= seatNum <= 500)
- 员工的进出顺序 seatOrLeave 数组,元素值为 1,表示进场;元素值为负数,表示出场(特殊:位置 0 的员工不会离开)。
- 例如 - 4 表示坐在位置 4 的员工离开(保证有员工坐在该座位上)
三、输出描述
最后进来员工,他会坐在第几个位置,如果位置已满,则输出 - 1 。
1、输入
10
[1,1,1,1,-4,1]
2、输出
5
3、说明
核心思想:每当一个员工进入时,需要坐到最大社交距离。
0 0 0 0 0 0 0 0 0 0
- 第一次坐在了0的位置;1 0 0 0 0 0 0 0 0 0
- 第二次坐在了9的位置;1 0 0 0 0 0 0 0 0 1
- 第三次坐在了4的位置;1 0 0 0 1 0 0 0 0 1
- 第四次坐在了2的位置;1 0 1 0 1 0 0 0 0 1
- 第五次4离开了;1 0 1 0 0 0 0 0 0 1
- 第六次坐在了5的位置;1 0 1 0 0 1 0 0 0 1
四、解题思路
题目要求:每当一个员工进入时,需要坐到最大社交距离。
核心解题思路:
- 找到距离最远的两个1;
- 求其中间值,如果有两个,则取索引小的。
- 0表示无人坐,1表示有人坐;
- 第一个人坐在0的位置,第二个人坐在离0最远的的n-1位置;
- 两头都有人坐了,则找到距离最远的两个1,求其中间值,如果有两个,则取索引小的;
- 通过遍历已经坐过的位置sitArr,获取两个1的最远距离;
- 再通过折半取值,获取中间值;
五、Java算法源码
public class Test02 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = Integer.valueOf(sc.nextLine());int[] seatArr = new int[n];String input = sc.nextLine();int[] arr = Arrays.stream(input.substring(1, input.length() - 1).split(",")).mapToInt(Integer::parseInt).toArray();int ans = findDistantSeat(arr, n);System.out.print(ans);}/*** 1、找到距离最远的两个1* 2、求其中间值,如果有两个,则取索引小的*/public static int findDistantSeat(int[] arr, int n) {// 已经坐人的位置TreeSet<Integer> treeSet = new TreeSet<>();for (int i = 0; i < arr.length; i++) {// 特殊情况,如果只有1个位置,则返回0if (arr.length == 1) {return 0;} else if (arr.length == 2) {// 如果只有2个位置,则返回1return n - 1;}// 元素值为负数,表示出场if (arr[i] < 0) {treeSet.remove(-arr[i]);continue;}int size = treeSet.size();// 已经坐人的位置为0,则表示无人坐,第一个人坐在0的位置if (size == 0) {treeSet.add(0);} else if (size == 1) { // 已经坐人的位置为1,则表示0处有人,第二个人坐在离0最远的的n-1位置treeSet.add(n - 1);} else if (size > 1 && size < n) {// 两头都有人坐了,则找到距离最远的两个1,求其中间值,如果有两个,则取索引小的// 已经坐过的位置int[] sitArr = new int[size];int count = 0;for (Integer seatedNum : treeSet) {sitArr[count++] = seatedNum;}// 两个1的最远距离int max = 0;int left = 0;for (int j = 0; j < sitArr.length - 1; j++) { // 计算最远距离int distance = sitArr[j + 1] - sitArr[j];// 获取两个1的最远距离if (distance / 2 > max) {max = distance / 2;left = sitArr[j];}}// 已经坐人的位置+1treeSet.add(left + max);if (i == arr.length - 1) {return left + max;}} else if (size == n) {// 如果位置已满,则输出 - 1return -1;}}// 异常情况返回-1return -1;}
}
六、效果展示
1、输入
12
[1,1,1,1,1,-2,-5,1]
2、输出
4
3、说明
- 第1次坐在了0的位置;1 0 0 0 0 0 0 0 0 0 0 0
- 第2次坐在了11的位置;1 0 0 0 0 0 0 0 0 0 0 1
- 第3次坐在了5的位置;1 0 0 0 0 1 0 0 0 0 0 1
- 第4次坐在了8的位置;1 0 0 0 0 1 0 0 1 0 0 1
- 第5次坐在了2的位置;1 0 1 0 0 1 0 0 1 0 0 1
- 第6次2离开了;1 0 1 0 0 1 0 0 1 0 0 1
- 第7次5离开了;1 0 0 0 0 0 0 0 1 0 0 1
- 第8次坐在了4的位置;1 0 0 0 1 0 0 0 1 0 0 1
🏆下一篇:华为OD机试 - 简易内存池 - 逻辑分析(Java 2024 C卷 200分)
🏆本文收录于,华为OD机试(JAVA)真题(A卷+B卷+C卷)
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。