题目链接
题目描述
分析一批天体观测数据,数据格式为 id t
,其中 是天体标识符,
是观测时间戳。数据已按时间戳
升序排列。
定义“观测间隔”为某次观测与前一次观测的时间差。对于任务的第一次观测,其观测间隔为该次观测的时间戳与 的差。
任务是找出产生最短观测间隔和最长观测间隔的天体 。如果多个天体的观测间隔相同,则选择数值最小的那个天体
。
输入:
- 多行输入,每行包含一个天体标识符
和一个时间戳
,由空格分隔。
输出:
- 一行输出两个整数,分别是具有最短观测间隔的天体
和具有最长观测间隔的天体
。
解题思路
这是一个模拟和最值求解问题。由于输入数据已经按照时间戳 进行了排序,我们可以一次遍历就解决问题。
我们需要维护几个变量:
:上一次观测的时间戳,初始为
。
:记录当前找到的最短观测间隔,初始为一个极大值。
:记录当前找到的最长观测间隔,初始为一个极小值(例如
)。
:与最短观测间隔对应的天体
。
:与最长观测间隔对应的天体
。
遍历每一条观测记录 (,
):
- 计算当前观测间隔:
。
- 更新最短间隔信息:
- 如果
,说明我们找到了一个新的更短的间隔。更新
和
。
- 如果
,发生了并列情况。根据题意,选择数值更小的
,即
。
- 如果
- 更新最长间隔信息:
- 如果
,说明我们找到了一个新的更长的间隔。更新
和
。
- 如果
,发生了并列情况。根据题意,选择数值更小的
,即
。
- 如果
- 更新上一次观测的时间戳:
,为下一次计算做准备。
遍历结束后, 和
就是我们要求的结果。
代码
#include <iostream>
#include <algorithm>
#include <limits>
using namespace std;
int main() {
int id, t;
int prev_t = 0;
// 初始化最短和最长间隔信息
int min_interval = numeric_limits<int>::max();
int max_interval = -1;
int min_id = 0;
int max_id = 0;
// 逐行读取输入
while (cin >> id >> t) {
// 计算当前观测间隔
int interval = t - prev_t;
// 更新最短间隔信息
if (interval < min_interval) {
min_interval = interval;
min_id = id;
} else if (interval == min_interval) {
min_id = min(min_id, id);
}
// 更新最长间隔信息
if (interval > max_interval) {
max_interval = interval;
max_id = id;
} else if (interval == max_interval) {
max_id = min(max_id, id);
}
// 更新上一个时间戳
prev_t = t;
}
// 输出结果
cout << min_id << " " << max_id << endl;
return 0;
}
import java.util.Scanner;
import java.lang.Math;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int prev_t = 0;
// 初始化最短和最长间隔信息
int min_interval = Integer.MAX_VALUE;
int max_interval = -1;
int min_id = 0;
int max_id = 0;
// 逐行读取输入
while (sc.hasNextInt()) {
int id = sc.nextInt();
int t = sc.nextInt();
// 计算当前观测间隔
int interval = t - prev_t;
// 更新最短间隔信息
if (interval < min_interval) {
min_interval = interval;
min_id = id;
} else if (interval == min_interval) {
min_id = Math.min(min_id, id);
}
// 更新最长间隔信息
if (interval > max_interval) {
max_interval = interval;
max_id = id;
} else if (interval == max_interval) {
max_id = Math.min(max_id, id);
}
// 更新上一个时间戳
prev_t = t;
}
// 输出结果
System.out.println(min_id + " " + max_id);
}
}
import sys
# 初始化上一个时间戳
prev_t = 0
# 初始化最短和最长间隔信息
min_interval = float('inf')
max_interval = -1
min_id = 0
max_id = 0
# 逐行读取输入
for line in sys.stdin:
parts = line.split()
if not parts:
continue
id = int(parts[0])
t = int(parts[1])
# 计算当前观测间隔
interval = t - prev_t
# 更新最短间隔信息
if interval < min_interval:
min_interval = interval
min_id = id
elif interval == min_interval:
min_id = min(min_id, id)
# 更新最长间隔信息
if interval > max_interval:
max_interval = interval
max_id = id
elif interval == max_interval:
max_id = min(max_id, id)
# 更新上一个时间戳
prev_t = t
# 输出结果
print(min_id, max_id)
算法及复杂度
- 算法:单次遍历 + 最值求解
- 时间复杂度:
,其中
是观测记录的总数。我们只需要对输入数据进行一次线性扫描。
- 空间复杂度:
,我们只使用了有限的几个变量来存储状态,与输入规模无关。