
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
一、题目描述
某公司举行招聘会,面试官通过叫号系统,按照应聘者的预约先后次序依次呼叫应聘者面试。
如果被叫到的应聘者没有及时到场,面试官叫不到人就会过号处理。
第一次过号的应聘者会被安排到下一位,第二次过号则会排队下两位,第三次过号则会被安排到下四位。
以此类推,按2^x的次序计算步长,过号次数越多则排队越后,直至队尾。也有人因为某些原因需要优先面试,优先面试的人会被提前叫号,如果优先面试的人未及时到场,则取消优先面试资格,按约定规则处理。
请写一段程序,实现以上排队叫号功能。
二、输入描述
每行输入1个应聘者预约消息,依次为应聘者编号、姓名、是否优先面试(true 是, false 否)、预约顺序(整数1至1000)、过号次数(整数0至10),最后一行以Exit结束。
三、输出描述
从第1个人开始叫号,输出所有被叫到的应聘者信息,格式为编号:姓名:是否过号(过号输出Y,否则输出N)
补充:不需要考虑人员自始至终未到场的情况。
四、测试用例
1、输入
A01 Oliver false 1 0
A02 James false 2 0
A03 william false 3 0
A04 Henry true 4 0
A05 Lucas true 5 0
Exit
2、输出
A04:Henry:N
A05:Lucas:N
A01:Oliver:N
A02:James:N
A03:William:N
3、说明
针对有设置优先面试、没有应聘者过号的场景依次输入5个应聘者预约信息,面试官依次叫号,因为编号A04、A05的应聘者设置了优先面试,并且A04的预约顺序是4,要先于A05,所以先输出A04,然后输出A05,然后按预约顺序依次输出A01、A02、A03
五、解题思路
这是一个动态队列模拟问题,核心规则包括:
- 基础顺序
- 先按“是否优先面试”
- 再按“预约顺序”
- 过号规则
- 第 x 次过号 → 向后移动 2^(x-1) 位
- 超出队尾 → 放到队尾
- 被过号的人 不会消失,后续仍会被叫到
- 优先面试规则
- 优先面试者一开始提前
- 如果优先面试者被过号一次 → 取消优先资格
- 输出
- 每次叫号都要输出
- 格式:编号:姓名:是否过号(Y/N)
六、Python算法源码
from collections import deque
import sys
import math
class Applicant:
def __init__(self, id, name, priority, order, miss):
self.id = id
self.name = name
self.priority = priority
self.order = order
self.miss = miss
apps = []
for line in sys.stdin:
if line.strip() == "Exit":
break
id, name, p, o, m = line.split()
apps.append(Applicant(id, name, p == "true", int(o), int(m)))
apps.sort(key=lambda x: (-x.priority, x.order))
queue = deque(apps)
while queue:
cur = queue.popleft()
if cur.miss > 0:
print(f"{cur.id}:{cur.name}:Y")
cur.priority = False
cur.miss -= 1
step = min(2 ** cur.miss, len(queue))
queue.insert(step, cur)
else:
print(f"{cur.id}:{cur.name}:N")
七、JavaScript算法源码
const fs = require("fs");
const lines = fs.readFileSync(0, "utf8").trim().split("\n");
class Applicant {
constructor(id, name, priority, order, miss) {
this.id = id;
this.name = name;
this.priority = priority;
this.order = order;
this.miss = miss;
}
}
let list = [];
for (let line of lines) {
if (line === "Exit") break;
let [id, name, p, o, m] = line.split(" ");
list.push(new Applicant(id, name, p === "true", +o, +m));
}
list.sort((a, b) => b.priority - a.priority || a.order - b.order);
while (list.length) {
let cur = list.shift();
if (cur.miss > 0) {
console.log(`${cur.id}:${cur.name}:Y`);
cur.priority = false;
cur.miss--;
let step = Math.min(2 ** cur.miss, list.length);
list.splice(step, 0, cur);
} else {
console.log(`${cur.id}:${cur.name}:N`);
}
}
八、C算法源码
#include <stdio.h>
#include <string.h>
#include <math.h>
typedef struct {
char id[10];
char name[20];
int priority;
int order;
int miss;
} Applicant;
Applicant queue[1000];
int size = 0;
int main() {
while (1) {
Applicant a;
char p[10];
if (scanf("%s", a.id) == EOF) break;
if (strcmp(a.id, "Exit") == 0) break;
scanf("%s %s %d %d", a.name, p, &a.order, &a.miss);
a.priority = strcmp(p, "true") == 0;
queue[size++] = a;
}
// 简单冒泡排序
for (int i = 0; i < size; i++)
for (int j = i + 1; j < size; j++)
if (queue[i].priority < queue[j].priority ||
(queue[i].priority == queue[j].priority && queue[i].order > queue[j].order)) {
Applicant t = queue[i];
queue[i] = queue[j];
queue[j] = t;
}
while (size > 0) {
Applicant cur = queue[0];
for (int i = 1; i < size; i++) queue[i - 1] = queue[i];
size--;
if (cur.miss > 0) {
printf("%s:%s:Y\n", cur.id, cur.name);
cur.miss--;
int step = fmin(pow(2, cur.miss), size);
for (int i = size; i > step; i--) queue[i] = queue[i - 1];
queue[step] = cur;
size++;
} else {
printf("%s:%s:N\n", cur.id, cur.name);
}
}
}
九、C++算法源码
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
struct Applicant {
string id, name;
bool priority;
int order, miss;
};
int main() {
vector<Applicant> q;
while (true) {
Applicant a;
cin >> a.id;
if (a.id == "Exit") break;
string p;
cin >> a.name >> p >> a.order >> a.miss;
a.priority = (p == "true");
q.push_back(a);
}
sort(q.begin(), q.end(), [](auto &a, auto &b) {
if (a.priority != b.priority) return a.priority > b.priority;
return a.order < b.order;
});
while (!q.empty()) {
Applicant cur = q.front();
q.erase(q.begin());
if (cur.miss > 0) {
cout << cur.id << ":" << cur.name << ":Y\n";
cur.miss--;
int step = min((int)pow(2, cur.miss), (int)q.size());
q.insert(q.begin() + step, cur);
} else {
cout << cur.id << ":" << cur.name << ":N\n";
}
}
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 双机位C卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

35

被折叠的 条评论
为什么被折叠?



