华为OD机试 - 最大社交距离 - TreeSet(Python/JS/C/C++ 2024 C卷 100分)

devtools/2024/11/13 22:39:53/

在这里插入图片描述

华为OD机试 2024E卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

一、题目描述

疫情期间需要大家保证一定的社交距离,公司组织开交流会议。

座位一排共 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

  1. 第一次坐在了0的位置;1 0 0 0 0 0 0 0 0 0
  2. 第二次坐在了9的位置;1 0 0 0 0 0 0 0 0 1
  3. 第三次坐在了4的位置;1 0 0 0 1 0 0 0 0 1
  4. 第四次坐在了2的位置;1 0 1 0 1 0 0 0 0 1
  5. 第五次4离开了;1 0 1 0 0 0 0 0 0 1
  6. 第六次坐在了5的位置;1 0 1 0 0 1 0 0 0 1

四、测试用例

测试用例1

1、输入

10
[1,1,1,1,-4,1]

2、输出

5

3、说明

核心思想:每当一个员工进入时,需要坐到最大社交距离。

0 0 0 0 0 0 0 0 0 0

  1. 第一次坐在了0的位置;1 0 0 0 0 0 0 0 0 0
  2. 第二次坐在了9的位置;1 0 0 0 0 0 0 0 0 1
  3. 第三次坐在了4的位置;1 0 0 0 1 0 0 0 0 1
  4. 第四次坐在了2的位置;1 0 1 0 1 0 0 0 0 1
  5. 第五次4离开了;1 0 1 0 0 0 0 0 0 1
  6. 第六次坐在了5的位置;1 0 1 0 0 1 0 0 0 1

测试用例2

1、输入

12
[1,1,1,1,1,-2,-5,1]

2、输出

4

3、说明

  1. 第1次坐在了0的位置;1 0 0 0 0 0 0 0 0 0 0 0
  2. 第2次坐在了11的位置;1 0 0 0 0 0 0 0 0 0 0 1
  3. 第3次坐在了5的位置;1 0 0 0 0 1 0 0 0 0 0 1
  4. 第4次坐在了8的位置;1 0 0 0 0 1 0 0 1 0 0 1
  5. 第5次坐在了2的位置;1 0 1 0 0 1 0 0 1 0 0 1
  6. 第6次2离开了;1 0 1 0 0 1 0 0 1 0 0 1
  7. 第7次5离开了;1 0 0 0 0 0 0 0 1 0 0 1
  8. 第8次坐在了4的位置;1 0 0 0 1 0 0 0 1 0 0 1

五、解题思路

题目要求:每当一个员工进入时,需要坐到最大社交距离。

核心解题思路:

  1. 找到距离最远的两个1;
  2. 求其中间值,如果有两个,则取索引小的。

  1. 0表示无人坐,1表示有人坐;
  2. 第一个人坐在0的位置,第二个人坐在离0最远的的n-1位置;
  3. 两头都有人坐了,则找到距离最远的两个1,求其中间值,如果有两个,则取索引小的;
  4. 通过遍历已经坐过的位置sitArr,获取两个1的最远距离;
  5. 再通过折半取值,获取中间值;

六、Python算法源码

python">import sysdef find_distant_seat(arr, n):# 使用有序列表存储已占座位occupied = set()occupied_ordered = []last_seat = -1for command in arr:if command > 0:  # 进场if not occupied:occupied.add(0)occupied_ordered.append(0)last_seat = 0else:max_dist = 0seat = -1# 排序已占座位occupied_ordered.sort()# 检查第一个座位到第一个已占座位的距离first = occupied_ordered[0]if first != 0 and first > max_dist:max_dist = firstseat = 0# 检查两个已占座位之间的距离for i in range(1, len(occupied_ordered)):prev = occupied_ordered[i-1]current = occupied_ordered[i]dist = (current - prev) // 2candidate = prev + distif dist > max_dist:max_dist = distseat = candidate# 检查最后一个已占座位到最后一个座位的距离last = occupied_ordered[-1]if (n - 1 - last) > max_dist:seat = n -1if seat != -1 and seat not in occupied:occupied.add(seat)occupied_ordered.append(seat)last_seat = seatelse:last_seat = -1breakelse:  # 出场leave_seat = -commandif leave_seat != 0 and leave_seat in occupied:occupied.remove(leave_seat)occupied_ordered.remove(leave_seat)# 检查最后一个命令是否为进场,且座位未满if arr and arr[-1] > 0:if len(occupied) <= n:return last_seatelse:return -1return -1def main():# 读取输入n = int(sys.stdin.readline())input_line = sys.stdin.readline().strip()arr = list(map(int, input_line[1:-1].split(',')))# 计算结果ans = find_distant_seat(arr, n)# 输出结果print(ans)if __name__ == "__main__":main()

七、JavaScript算法源码

javascript">function findDistantSeat(arr, n) {// 使用有序数组存储已占座位let occupied = new Set();let occupiedOrdered = [];let lastSeat = -1;for (let command of arr) {if (command > 0) { // 进场if (occupied.size === 0) {occupied.add(0);occupiedOrdered.push(0);lastSeat = 0;} else {let maxDist = 0;let seat = -1;// 排序已占座位occupiedOrdered.sort((a, b) => a - b);// 检查第一个座位到第一个已占座位的距离let first = occupiedOrdered[0];if (first !== 0 && first > maxDist) {maxDist = first;seat = 0;}// 检查两个已占座位之间的距离for (let i = 1; i < occupiedOrdered.length; i++) {let prev = occupiedOrdered[i-1];let current = occupiedOrdered[i];let dist = Math.floor((current - prev) / 2);let candidate = prev + dist;if (dist > maxDist) {maxDist = dist;seat = candidate;}}// 检查最后一个已占座位到最后一个座位的距离let last = occupiedOrdered[occupiedOrdered.length -1];if ((n -1 - last) > maxDist) {seat = n -1;}if (seat !== -1 && !occupied.has(seat)) {occupied.add(seat);occupiedOrdered.push(seat);lastSeat = seat;} else {lastSeat = -1;break;}}} else { // 出场let leaveSeat = -command;if (leaveSeat !== 0 && occupied.has(leaveSeat)) {occupied.delete(leaveSeat);occupiedOrdered = occupiedOrdered.filter(seat => seat !== leaveSeat);}}}// 检查最后一个命令是否为进场,且座位未满if (arr.length > 0 && arr[arr.length -1] > 0) {if (occupied.size <= n) {return lastSeat;} else {return -1;}}return -1;
}// 读取输入并处理
function main() {const fs = require('fs');const input = fs.readFileSync('/dev/stdin', 'utf8').trim().split('\n');const n = parseInt(input[0]);const arr = input[1].slice(1, -1).split(',').map(Number);const ans = findDistantSeat(arr, n);console.log(ans);
}main();

八、C算法源码

#include <stdio.h>
#include <stdlib.h>typedef struct {int *data;int size;int capacity;
} TreeSet;void initSet(TreeSet *set) {set->capacity = 10;set->size = 0;set->data = (int *)malloc(set->capacity * sizeof(int));
}void addSet(TreeSet *set, int val) {// 简单插入保持有序if (set->size == set->capacity) {set->capacity *=2;set->data = (int *)realloc(set->data, set->capacity * sizeof(int));}int i =0;while(i < set->size && set->data[i] < val) i++;for(int j = set->size; j > i; j--){set->data[j] = set->data[j-1];}set->data[i] = val;set->size++;
}void removeSet(TreeSet *set, int val) {int i=0;while(i < set->size && set->data[i] != val) i++;if(i < set->size){for(int j=i; j < set->size -1; j++) {set->data[j] = set->data[j+1];}set->size--;}
}int findDistantSeat(int arr[], int m, int n){TreeSet occupied;initSet(&occupied);int lastSeat = -1;for(int i=0; i<m; i++){int command = arr[i];if(command >0){ // 进场if(occupied.size ==0){addSet(&occupied, 0);lastSeat =0;}else{int maxDist =0;int seat = -1;// 检查第一个座位到第一个已占座位的距离int first = occupied.data[0];if(first !=0 && first > maxDist){maxDist = first;seat =0;}// 检查两个已占座位之间的距离for(int j=1; j < occupied.size; j++){int prev = occupied.data[j-1];int current = occupied.data[j];int dist = (current - prev)/2;int candidate = prev + dist;if(dist > maxDist){maxDist = dist;seat = candidate;}}// 检查最后一个已占座位到最后一个座位的距离int last = occupied.data[occupied.size -1];if((n-1 - last) > maxDist){seat = n-1;}if(seat != -1){addSet(&occupied, seat);lastSeat = seat;}else{lastSeat = -1;break;}}}else{ // 出场int leaveSeat = -command;if(leaveSeat !=0){removeSet(&occupied, leaveSeat);}}}// 检查最后一个命令是否为进场,且座位未满if(m >0 && arr[m-1] >0){if(occupied.size <=n){return lastSeat;}else{return -1;}}return -1;
}int main(){int n;scanf("%d", &n);char input[1000];scanf(" %[^\n]", input);int arr[500], m=0;char *token = strtok(input, ",[] ");while(token != NULL){arr[m++] = atoi(token);token = strtok(NULL, ",[] ");}int ans = findDistantSeat(arr, m, n);printf("%d", ans);return 0;
}

九、C++算法源码

#include <bits/stdc++.h>
using namespace std;int findDistantSeat(vector<int> arr, int n){set<int> occupied;int lastSeat = -1;for(auto command: arr){if(command >0){ // 进场if(occupied.empty()){occupied.insert(0);lastSeat =0;}else{int maxDist =0;int seat = -1;// 检查第一个座位到第一个已占座位的距离int first = *occupied.begin();if(first !=0 && first > maxDist){maxDist = first;seat =0;}// 检查两个已占座位之间的距离auto prev = occupied.begin();for(auto it = next(occupied.begin()); it != occupied.end(); ++it){int current = *it;int dist = (*it - *prev)/2;int candidate = *prev + dist;if(dist > maxDist){maxDist = dist;seat = candidate;}prev = it;}// 检查最后一个已占座位到最后一个座位的距离int last = *occupied.rbegin();if((n-1 - last) > maxDist){seat = n-1;}if(seat != -1){occupied.insert(seat);lastSeat = seat;}else{lastSeat = -1;break;}}}else{ // 出场int leaveSeat = -command;if(leaveSeat !=0){occupied.erase(leaveSeat);}}}// 检查最后一个命令是否为进场,且座位未满if(!arr.empty() && arr.back() >0){if(occupied.size() <=n){return lastSeat;}else{return -1;}}return -1;
}int main(){int n;cin >> n;string input;cin >> input;vector<int> arr;int num =0;bool negative = false;for(char c: input){if(c == '[' || c == ']' || c == ',') continue;if(c == '-'){negative = true;}else{if(isdigit(c)){num = num *10 + (c - '0');}else{if(negative){num = -num;}arr.push_back(num);num =0;negative = false;}}}// 添加最后一个数字if(input.back() != ',' && input.back() != ']'){if(negative){num = -num;}arr.push_back(num);}int ans = findDistantSeat(arr, n);cout << ans;
}

🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

在这里插入图片描述


http://www.ppmy.cn/devtools/133409.html

相关文章

ssm087会议管理系统ssm(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;会议管理系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本会议管理系统就是在这…

深⼊理解指针(5)[回调函数、qsort相关知识(qsort可用于各种类型变量的排序)】

目录 1. 回调函数 2. qsort相关知识&#xff08;qsort可用于各种类型变量的排序&#xff09; 一 回调函数 1定义/作用:把函数的指针&#xff08;地址&#xff09;作为参数传递给另⼀个函数&#xff0c;当这个指针被⽤来调⽤其所指向的函数 时&#xff0c;被调⽤的函数就…

.net core开发windows程序在国产麒麟操作系统中运行

.net core自从3.1版本号后&#xff0c;完全是一个独立的开源的多平台开发组件&#xff0c;目前国产化是趋势&#xff0c;不少项目需要开发国产如Kylin操作系统中运行的程序&#xff0c;无论是Web程序还是桌面程序&#xff0c;都有这样的需求。 首先&#xff0c;可明确的的.net…

如何在CentOS 7上搭建SMB服务

如何在CentOS 7上搭建SMB服务 因项目测试需求&#xff0c;需要自行搭建SMB服务&#xff0c;**SMB&#xff08;Server Message Block&#xff09;**协议是一种常用的文件共享方式&#xff0c;它可以让不同操作系统之间共享文件、打印机等资源。本文将带你一步步搭建一个简单的S…

c文件的编译,汇编,基础知识

文章目录 前言一、预编译二、编译阶段三、汇编1&#xff0c; objdump的用法2&#xff0c;objdump 举例objdump -s hello.o 输出&#xff08;节内容&#xff09; 四&#xff0c;代码段 前言 #include <stdio.h> int main(){printf("hello, world\n");}从这个最…

Python学习从0到1 day26 第三阶段 Spark ① 数据输入

要学会 剥落旧痂 然后 循此新生 —— 24.11.8 一、Spark是什么 定义&#xff1a; Apache Spark 是用于大规模数据处理的统一分析引擎 简单来说&#xff0c;Spark是一款分布式的计算框架&#xff0c;用于调度成百上千的服务器集群&#xff0c;计算TB、PB乃至EB级别的海量数据…

电子商务网站之首页设计

本文 以表格布局方式实现一电 子商务网站首页&#xff0c;结合php[mysql获取后端数据 。首页通常包括网店Logo、导航条、搜索、商品展示等&#xff0c;网页头部和脚部已经制作成两件&#xff0c;直接调用即可&#xff0c;导航还需设计一个商品类别导航&#xff0c;商品展示分为…

基于微信小程序的移动学习平台的设计与实现+ssm(lw+演示+源码+运行)

摘 要 由于APP软件在开发以及运营上面所需成本较高&#xff0c;而用户手机需要安装各种APP软件&#xff0c;因此占用用户过多的手机存储空间&#xff0c;导致用户手机运行缓慢&#xff0c;体验度比较差&#xff0c;进而导致用户会卸载非必要的APP&#xff0c;倒逼管理者必须改…