题目描述
当小区通信设备上报警时,系统会自动生成待处理的工单,华为工单调度系统需要根据不同的策略,调度外线工程师(FME)上站修复工单对应的问题。
根据与运营商签订的合同,不同严重程度的工单被处理并修复的时长要求不同,这个要求被修复的时长我们称之为SLA时间。
假设华为和运营商A签订了运维合同,部署了一套调度系统,只有1个外线工程师(FME),每个工单根据问题严重程度会给一个评分,在SLA时间内完成修复的工单,华为获得工单评分对应的积分,超过SLA完成的工单不获得积分,但必须完成该工单。运营商最终会根据积分进行付款。
请设计一种调度策略,根据现状得到调度结果完成所有工单,让这个外线工程师处理的工单获得的总积分最多。
假设从某个调度时刻开始,当前工单数量为N,不会产生新的工单,每个工单处理修复耗时为1小时,请设计你的调度策略,完成业务目标。
不考虑外线工程师在小区之间行驶的耗时。
输入描述
第一行为一个整数N,表示工单的数量。
接下来N行,每行包括两个整数。第一个整数表示工单的SLA时间(小时),第二个数表示该工单的积分。
输出描述
输出一个整数表示可以获得的最大积分。
备注
- 工单数量N ≤ 10^6
- SLA时间 ≤ 7 * 10^5
- 答案的最大积分不会超过2147483647
用例
假设有7个工单的SLA时间(小时)和积分如下:
工单编号 | SLA | 积分 |
1 | 1 | 6 |
2 | 1 | 7 |
3 | 3 | 2 |
4 | 3 | 1 |
5 | 2 | 4 |
6 | 2 | 5 |
7 | 6 | 1 |
输入 | 7 1 6 1 7 3 2 3 1 2 4 2 5 6 1 |
输出 | 15 |
说明 | 最多可获得15积分,其中一个调度结果完成工单顺序为2,6,3,1,7,5,4(可能还有其他顺序) |
解析
题目要求在给定的工单列表中设计调度策略,以便外线工程师处理工单时获得的总积分最大化。每个工单都有一个规定的SLA时间,如果在该时间内完成,则可以获得相应的积分。如果超出SLA时间完成工单,则只能获得积分中的一部分。
解决思路:
-
问题分析:
- 题目中要求我们在限定时间内,按照某种调度顺序处理工单,以最大化最终得到的积分。
- 由于每个工单的处理时间固定为1小时,因此我们可以根据每个工单的SLA时间和积分,确定一个最优的处理顺序,使得工程师的总得分最高。
- 如果我们按照工单的SLA时间从小到大进行排序,优先处理那些SLA时间较短的工单,可以避免较多的工单因超时而扣分。
-
算法策略:
- 首先根据工单的SLA时间对工单进行排序,优先处理SLA时间短的工单。
- 按照排序后的顺序逐个处理工单,并计算在规定时间内完成的工单得分累计和。
- 如果超出了SLA时间,可以根据工单的实际处理情况,计算部分得分。
C语言代码实现
以下是根据上述思路的C语言代码实现:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int sla;
int score;
} WorkOrder;
int compare(const void *a, const void *b) {
return ((WorkOrder *)a)->sla - ((WorkOrder *)b)->sla;
}
int main() {
int n;
scanf("%d", &n);
WorkOrder orders[n];
for (int i = 0; i < n; i++) {
scanf("%d %d", &orders[i].sla, &orders[i].score);
}
// 按照SLA时间排序
qsort(orders, n, sizeof(WorkOrder), compare);
long long total_score = 0;
int current_time = 0;
for (int i = 0; i < n; i++) {
if (current_time < orders[i].sla) {
total_score += orders[i].score;
current_time++;
} else {
total_score += orders[i].score / 2; // 超时只能得到一半的积分
current_time++;
}
}
printf("%lld\n", total_score);
return 0;
}
代码说明
- 结构体
WorkOrder
: 用于存储每个工单的SLA时间和积分。 qsort
函数: 按照工单的SLA时间对工单进行排序,优先处理SLA时间短的工单。- 循环处理工单: 根据当前时间和工单的SLA时间,确定工单是否可以在SLA时间内完成,计算得分。
- 输出部分: 输出最终获得的总积分。
Python 代码实现
将上述C语言代码转换成Python代码如下:
def max_total_score(n, orders):
# 按照SLA时间排序
orders.sort(key=lambda x: x[0])
total_score = 0
current_time = 0
for sla, score in orders:
if current_time < sla:
total_score += score
current_time += 1
else:
total_score += score // 2 # 超时只能得到一半的积分
current_time += 1
return total_score
# 输入部分
n = int(input())
orders = [tuple(map(int, input().split())) for _ in range(n)]
# 计算最大总积分
result = max_total_score(n, orders)
# 输出结果
print(result)
代码说明
- 函数
max_total_score
: 计算外线工程师处理工单的最大总积分。 - 排序部分: 按照SLA时间对工单进行排序,优先处理SLA时间短的工单。
- 处理过程: 按顺序处理工单,根据实际情况计算得分。
- 输入和输出: 接收工单数据并输出最终的总积分。