华为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个位置,则返回0
if (arr.length == 1) {
return 0;
} else if (arr.length == 2) {// 如果只有2个位置,则返回1
return 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];
}
}
// 已经坐人的位置+1
treeSet.add(left + max);
if (i == arr.length - 1) {
return left + max;
}
} else if (size == n) {// 如果位置已满,则输出 - 1
return -1;
}
}
// 异常情况返回-1
return -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在线答疑。