#P2628. 告警计算
-
1000ms
Tried: 114
Accepted: 33
Difficulty: 5
所属公司 :
华为
时间 :2024年12月11日-留学生
-
算法标签>模拟
告警计算
题解
题目描述
一位工程师为服务运行的主机配置了针对 CPU 的监控告警,想知道在一段时间内该主机上报了多少次告警。CPU 监控数据以字符串数组 dataItems 的形式存在。
告警触发规则:
- 当在最近的时间段 interval 内,监控值连续 limit 次大于等于 CPU 使用率阈值 threshold 时,则触发上报告警。
- 如果持续满足告警上报条件,可以多次上报告警。
解题思路
我们需要统计在指定的时间段内,主机上报了多少次针对CPU使用率的告警。告警触发的条件是,在最近的 interval 秒内,监控数据中连续有 limit 次 CPU 使用率大于等于 threshold。如果条件持续满足,可以多次上报告警。
具体步骤如下:
-
输入解析:
- 读取监控数据总数
n。 - 读取
n条监控数据,解析出每条数据的 CPU 使用率和时间戳。 - 读取时间段
interval,阈值threshold和上报阈值limit。
- 读取监控数据总数
-
确定时间窗口:
- 获取最新的时间戳
latest_timestamp。 - 计算时间窗口的起始时间
window_start = latest_timestamp - interval + 1(包括两端)。
- 获取最新的时间戳
-
遍历监控数据,统计告警次数:
- 对于每条监控数据,检查其时间戳是否在时间窗口内。
- 如果在时间窗口内,并且 CPU 使用率大于等于
threshold,则增加当前的连续计数current_streak。 - 如果
current_streak达到或超过limit,则触发一次告警,增加告警次数res。 - 如果遇到不满足条件的监控数据,则重置
current_streak。
-
输出结果:
- 输出总的告警次数
res。
- 输出总的告警次数
cpp
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
using namespace std;
int main() {
int dataItemsLength;
cin >> dataItemsLength; // 监控数据总个数
vector<pair<int, int>> monitoringData; // 存储CPU使用率和时间戳
string dataItem;
for(int i = 0; i < dataItemsLength; ++i){
cin >> dataItem;
int cpuUsage, timestamp;
size_t commaPos = dataItem.find(',');
cpuUsage = stoi(dataItem.substr(0, commaPos));
timestamp = stoi(dataItem.substr(commaPos + 1));
monitoringData.emplace_back(cpuUsage, timestamp);
}
int interval; // 告警统计时间段
cin >> interval;
int threshold; // 告警计算阈值
cin >> threshold;
int limit; // 告警上报阈值
cin >> limit;
int alertCount = 0; // 告警次数
for(int i = 0; i < dataItemsLength; ++i){
int windowStart = monitoringData[i].second - interval + 1; // 时间窗口起始点
int consecutiveCount = 0; // 连续满足条件的次数
for(int j = i; j >= 0; --j){
if(monitoringData[j].first < threshold || monitoringData[j].second < windowStart){
break;
}
consecutiveCount++;
if(consecutiveCount >= limit){
alertCount++;
break;
}
}
}
cout << alertCount << endl; // 输出告警次数
return 0;
}
python
n = int(input()) # 监控数据总个数
monitoring_line = input().split(" ") # 监控数据列表
interval = int(input()) # 告警统计时间段(秒)
threshold = int(input()) # 告警计算阈值(百分比)
limit = int(input()) # 告警上报阈值
data = []
for s in monitoring_line:
cpu_usage, timestamp = map(int, s.split(","))
data.append([cpu_usage, timestamp])
alert_count = 0 # 告警次数
for i in range(n):
window_start = data[i][1] - interval + 1 # 时间窗口起始点
consecutive_count = 0 # 连续满足条件的次数
for j in range(i, -1, -1):
if data[j][0] < threshold or data[j][1] < window_start:
break
consecutive_count += 1
if consecutive_count >= limit:
alert_count += 1
break
print(alert_count)
java
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int dataItemsLength = Integer.parseInt(br.readLine().trim()); // 监控数据总个数
String[] monitoringLine = br.readLine().trim().split(" "); // 监控数据列表
int interval = Integer.parseInt(br.readLine().trim()); // 告警统计时间段
int threshold = Integer.parseInt(br.readLine().trim()); // 告警计算阈值
int limit = Integer.parseInt(br.readLine().trim()); // 告警上报阈值
List<int[]> monitoringData = new ArrayList<>(); // 存储CPU使用率和时间戳
for(String s : monitoringLine){
String[] parts = s.split(",");
int cpuUsage = Integer.parseInt(parts[0]);
int timestamp = Integer.parseInt(parts[1]);
monitoringData.add(new int[]{cpuUsage, timestamp});
}
int alertCount = 0; // 告警次数
for(int i = 0; i < dataItemsLength; i++){
int windowStart = monitoringData.get(i)[1] - interval + 1; // 时间窗口起始点
int consecutiveCount = 0; // 连续满足条件的次数
for(int j = i; j >= 0; j--){
if(monitoringData.get(j)[0] < threshold || monitoringData.get(j)[1] < windowStart){
break;
}
consecutiveCount++;
if(consecutiveCount >= limit){
alertCount++;
break;
}
}
}
System.out.println(alertCount); // 输出告警次数
}
}
题目内容
一位工程师给服务运行的主机配置了针对 CPU 的监控告警,想知道一段时间内该主机上报了多少次告警。CPU 监控数据以字符串数组 dataItems 形式存在。
告警触发规则:当满足最近时间段 interval 内,监控值连续 limit 次大于等于 CPU 使用率阈值 threshold 时,则触发上报告警,如果持续满足告警上报条件,可以多次上报告警。
请你返回该主机上报告警的总次数。
输入描述
入参分为五行输入:
第一行:监控数据总个数 dataItemsLength ,整数,单位个,例如 3
第二行:监控数据 dataItems ,字符串数组形式,其中 dataItems[i] 是第 i 条监控数据,包括当前 CPU 使用率值(取值范围 0~100 ,整数)和当前时间戳(取值范围 0~2147483647,整数,以升序排列)两部分内容,以英文逗号分隔,例如:65,1705386526。元素间以空格分隔,例如:85,1705386526 80,1705386528 95,1705386530 90,1705386531 92,1705386532
第三行:告警统计时间段 interval ,整数,单位是秒,例如 4 ,表示假定当前时间戳为1705386532 ,则统计从 1705386529 到 1705386532 时间范围内的数据,包含两端时间点的数据
第四行:告警计算阈值 threshold,整数,单位是百分比,例如 80
第五行:告警上报阈值 limit ,整数,单位个,例如 2
输入范围说明:
1≤dataItems.length≤86400
1≤interva≤86400
1≤threshold≤100
1≤limit≤100
输出描述
返回该主机上报告警的次数
样例1
输入
1
85,1705386526
1
80
1
输出
1
说明
最近 1 秒内,存在 1 条监控数据,连续超过 CPU 阈值 80 ,满足告警触发条件,最终上报 1 条告警
样例2
输入
5
85,1705386526 80,1705386528 95,1705386530 90,1705386531 92,1705386532
4
80
2
输出
4
说明
最近 4 秒内,存在 5 条监控数据,连续超过 CPU 阈值 80 ,其他 4 条监控数据(第 2、3、4、5 条)达到告警上报阈值 2 ,满足告警触发条件,最终上报 4 条告警