首页 > 试题广场 >

火星探测器稳定性分析

[编程题]火星探测器稳定性分析
  • 热度指数:2376 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
“祝融号”火星探测器在火星表面执行一项精密科学探测任务。其搭载的科学仪器对工作环境的稳定性有非常严苛的要求。为了保证仪器的正常运行和数据的准确性,必须满足以下两个条件:

1. 仪器的“环境稳定性指数” S 必须维持在 [18, 24] 的区间内,即 18 \le S \le 24
2. 在任何一次连续的工作期间内,环境稳定性指数的最大波动范围(即该期间的 S_{max} - S_{min})不得超过 4,即 S_{max} - S_{min} \le 4

现在,探测器沿一条预定路线行进,并按固定时间间隔连续采集了 N 次环境稳定性指数。这些数据按采集顺序(索引从 0 开始)记录下来。

为了最大化单次有效工作时长,请你找出满足上述两个稳定条件的、持续时间最长的一个或多个时间段。请输出这些时间段的起始和结束索引。如果存在多个长度相同的最长时间段,请按照起始索引从小到大的顺序,逐行输出。


输入描述:
第一行为连续采集的次数 N,其中 N 的取值范围为 [1, 10^5]
第二行为 N 个按顺序采集的环境稳定性指数,均为整数,数值范围为 [0, 30]。数值之间以空格分隔。


输出描述:
输出持续时间最长且满足稳定条件的时间段的起始索引和结束索引,两者以空格分隔。如果存在多个这样的时间段,按起始索引升序逐行输出。
示例1

输入

20
27 2 19 16 24 9 29 21 28 10 5 27 6 4 27 11 14 1 4 27

输出

2 2
4 4
7 7

备注:
本题由牛友@Charles 整理上传
#include <bits stdc++.h="">

using namespace std;
const int N = 100010;
int a[N];
int len;

int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i ++) cin >> a[i];
    vector> result;
    deque<int> qmin, qmax;
    int left = 0;
    for (int right = 0; right < n; right ++)  {
        if (a[right] > 24 || a[right] < 18) {
            qmin.clear();
            qmax.clear();
            left = right + 1;
            continue;
        }
        while (qmin.size() && a[qmin.back()] >= a[right]) qmin.pop_back();
        qmin.push_back(right);
        while (qmax.size() && a[qmax.back()] <= a[right]) qmax.pop_back();
        qmax.push_back(right);

        int cur_min = a[qmin.front()];
        int cur_max = a[qmax.front()];

        while (left <= right && cur_max - cur_min > 4) {
            if (qmin.front() == left) qmin.pop_front();
            if (qmax.front() == left) qmax.pop_front();
            left ++;
            if (qmin.size()) cur_min = a[qmin.front()];
            if (qmax.size()) cur_max = a[qmax.front()];
        }
        int length = right - left + 1;
        if (length > len) {
            len = length;
            result.clear();
            result.push_back({left, right});
        }
        else if (length == len) {
            result.push_back({left, right});
        }
    }
    for (auto seg : result) {
        cout << seg.first << " " << seg.second << endl;
    }
    return 0;
}
发表于 2025-09-16 18:32:53 回复(0)
import sys
from collections import deque
input = sys.stdin.readline

n = int(input())
data = list(map(int, input().split()))

ans = []
mx = 0

st_max = deque() 
st_min = deque() 
left = 0
for right, s in enumerate(data):
    if s < 18&nbs***bsp;s > 24:
        left = right + 1
        st_max.clear()
        st_min.clear()
    else:
        while st_max and data[st_max[-1]] < s:
            st_max.pop()
        st_max.append(right)
        while st_min and data[st_min[-1]] > s:
            st_min.pop()
        st_min.append(right)
        if st_max[0] < left:
            st_max.popleft()
        if st_min[0] < left:
            st_min.popleft()
        while data[st_max[0]] - data[st_min[0]] > 4:
            left += 1
            if st_max[0] < left:
                st_max.popleft()
            if st_min[0] < left:
                st_min.popleft()
        if right - left + 1 > mx:
            ans = [(left, right)]
            mx = right - left + 1
        elif right - left + 1 == mx:
            ans.append((left, right))

for i, j in ans:
    print(f"{i} {j}")
 使用滑动窗口+双端队列存储最大最小值
发表于 2025-09-05 22:15:35 回复(0)