#P3486. 第1题-冬季暖系统温度稳定性分析
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 1331
            Accepted: 284
            Difficulty: 5
            
          
          
          
                       所属公司 : 
                              华为
                                
            
                        
              时间 :2025年8月27日-国内-非AI方向(通软&嵌软&测试&算法&数据科学)
                              
                      
          
 
- 
                        算法标签>双指针          
 
第1题-冬季暖系统温度稳定性分析
思路
- 
双指针滑动窗口 + 单调队列维护区间最小值与最大值
- 设左右指针 l,r 表示当前窗口。
 - 两个单调队列分别维护区间内的最小值与最大值(存下标),支持 O(1) 获取当前 min 与 max。
 - 若遇到温度不在 [18,24],将窗口与队列清空,并令 l=r+1。
 - 每次加入新元素后,若 max−min>4,从左收缩窗口,同时维护队列头。
 - 用 bestLen 记录当前最长长度,长度相等则一并记录。
 
 
复杂度
- 时间复杂度:O(N)
 - 空间复杂度:O(N)(队列与结果存储)
 
C++
#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int N;
    if (!(cin >> N)) return 0;
    vector<int> a;
    a.reserve(N);
    int x;
    while ((int)a.size() < N && (cin >> x)) a.push_back(x);
    N = (int)a.size();
    deque<int> minq, maxq; // 存下标,minq 单调递增(值),maxq 单调递减(值)
    int l = 0;
    int bestLen = 0;
    vector<pair<int,int>> ans;
    for (int r = 0; r < N; ++r) {
        int v = a[r];
        // 若不在 [18,24],窗口重置
        if (v < 18 || v > 24) {
            minq.clear();
            maxq.clear();
            l = r + 1;
            continue;
        }
        // 维护单调队列(插入 r)
        while (!minq.empty() && a[minq.back()] >= v) minq.pop_back();
        minq.push_back(r);
        while (!maxq.empty() && a[maxq.back()] <= v) maxq.pop_back();
        maxq.push_back(r);
        // 收缩直到满足 max - min <= 4
        while (!minq.empty() && !maxq.empty() && a[maxq.front()] - a[minq.front()] > 4) {
            if (minq.front() == l) minq.pop_front();
            if (maxq.front() == l) maxq.pop_front();
            ++l;
        }
        // 记录答案
        int len = r - l + 1;
        if (len > 0) {
            if (len > bestLen) {
                bestLen = len;
                ans.clear();
                ans.emplace_back(l, r);
            } else if (len == bestLen) {
                ans.emplace_back(l, r);
            }
        }
    }
    for (auto &p : ans) {
        cout << p.first << ' ' << p.second << '\n';
    }
    return 0;
}
Python
import sys
from collections import deque
def main():
    data = list(map(int, sys.stdin.read().strip().split()))
    if not data:
        return
    N = data[0]
    arr = data[1:1+N]
    N = len(arr)
    minq = deque()  # 存下标,值单调递增
    maxq = deque()  # 存下标,值单调递减
    l = 0
    bestLen = 0
    ans = []
    for r in range(N):
        v = arr[r]
        # 不在 [18,24],重置窗口
        if v < 18 or v > 24:
            minq.clear()
            maxq.clear()
            l = r + 1
            continue
        # 插入 r,维护单调性
        while minq and arr[minq[-1]] >= v:
            minq.pop()
        minq.append(r)
        while maxq and arr[maxq[-1]] <= v:
            maxq.pop()
        maxq.append(r)
        # 收缩直到满足 max - min <= 4
        while minq and maxq and (arr[maxq[0]] - arr[minq[0]] > 4):
            if minq[0] == l:
                minq.popleft()
            if maxq[0] == l:
                maxq.popleft()
            l += 1
        length = r - l + 1
        if length > 0:
            if length > bestLen:
                bestLen = length
                ans = [(l, r)]
            elif length == bestLen:
                ans.append((l, r))
    out = sys.stdout
    for s, e in ans:
        out.write(f"{s} {e}\n")
if __name__ == "__main__":
    main()
Java
import java.io.*;
import java.util.*;
public class Main {
    public static void main(String[] args) throws Exception {
        FastScanner fs = new FastScanner(System.in);
        Integer nObj = fs.nextInt();
        if (nObj == null) return;
        int N = nObj;
        List<Integer> arrList = new ArrayList<>(N);
        for (int i = 0; i < N; i++) {
            Integer val = fs.nextInt();
            if (val == null) break;
            arrList.add(val);
        }
        int Nreal = arrList.size();
        int[] a = new int[Nreal];
        for (int i = 0; i < Nreal; i++) a[i] = arrList.get(i);
        Deque<Integer> minq = new ArrayDeque<>(); // 存下标,值单调递增
        Deque<Integer> maxq = new ArrayDeque<>(); // 存下标,值单调递减
        int l = 0, bestLen = 0;
        List<int[]> ans = new ArrayList<>();
        for (int r = 0; r < Nreal; r++) {
            int v = a[r];
            // 不在 [18,24],重置窗口
            if (v < 18 || v > 24) {
                minq.clear();
                maxq.clear();
                l = r + 1;
                continue;
            }
            // 插入 r,维护单调性
            while (!minq.isEmpty() && a[minq.peekLast()] >= v) minq.pollLast();
            minq.addLast(r);
            while (!maxq.isEmpty() && a[maxq.peekLast()] <= v) maxq.pollLast();
            maxq.addLast(r);
            // 收缩直到满足 max - min <= 4
            while (!minq.isEmpty() && !maxq.isEmpty() && (a[maxq.peekFirst()] - a[minq.peekFirst()] > 4)) {
                if (minq.peekFirst() == l) minq.pollFirst();
                if (maxq.peekFirst() == l) maxq.pollFirst();
                l++;
            }
            int len = r - l + 1;
            if (len > 0) {
                if (len > bestLen) {
                    bestLen = len;
                    ans.clear();
                    ans.add(new int[]{l, r});
                } else if (len == bestLen) {
                    ans.add(new int[]{l, r});
                }
            }
        }
        StringBuilder sb = new StringBuilder();
        for (int[] p : ans) {
            sb.append(p[0]).append(' ').append(p[1]).append('\n');
        }
        System.out.print(sb.toString());
    }
    // 简单快速输入
    static class FastScanner {
        private final InputStream in;
        private final byte[] buffer = new byte[1 << 16];
        private int ptr = 0, len = 0;
        FastScanner(InputStream is) { in = is; }
        private int read() throws IOException {
            if (ptr >= len) {
                len = in.read(buffer);
                ptr = 0;
                if (len <= 0) return -1;
            }
            return buffer[ptr++];
        }
        Integer nextInt() throws IOException {
            int c, sgn = 1, x = 0;
            do {
                c = read();
                if (c == -1) return null;
            } while (c <= ' ');
            if (c == '-') { sgn = -1; c = read(); }
            for (; c > ' '; c = read()) {
                if (c < '0' || c > '9') break;
                x = x * 10 + (c - '0');
            }
            return x * sgn;
        }
    }
}
        题目内容
某小区宣传其在冬季采暖期间,提供室内温度保持在18−24摄氏度之间,且温差在4摄氏度内的恒温服务。为了评价该小区冬季采暖温控效果,现按固定时间间隔对室内温度进行连续N次采样,采样的室内温度按照从0开始升序的索引号依次记录。
通过计算采样的室内温度在小区承诺恒温范围内的持续时间,即持续时间内的采样室内温度值T均满足 18≤T≤24,且持续时间内的温差(最大温度max - 最低温度min<=4),持续时间越长,采暖温控效果越好。
请输出最大的持续时间开始点和结束点的采样的室内温度索引号,如果存在多个最大持续时间,按持续时间的开始点采样的室内温度索引号升序,逐行输出。
输入描述
第一行输入为按固定时间间隔对室内温度进行连续采样次N。N的取值范围为[1,105]
第二行输入为按固定时间间隔采集的一段连续的室内温度数值,整型,温度数值取值范围[0,30] 。输入格式为:用空格分割的温度数值数组
输出描述
最大持续时间的开始点和结束点的数组元素索引号,中间用空格分隔。存在多组时逐行输出。说明:数组元素索引号从0开始。
样例1
输入
6
16 18 20 25 23 20
输出
1 2
4 5
说明
满足恒温要求的为数组索引1−2、数组索引4−5,按起始索引升序输出
样例2
输入
3
16 18 16
输出
1 1
说明
仅有一个温度18在承诺温度范围内,开始点和结束点的数组元素索引号相同均为1,因此输出1 1
样例3
输入
13
16 18 20 21 22 24 26 25 23 21 21 20 19
输出
8 12
说明
数组中索引1−4温度值为18 20 21 22,均满足18≤T≤24 ,且温差为 22−18=4≤4。持续时间为4;数组中索引8−12温度值为23 21 21 20 19,均满足18≤T≤24 ,且温差为23−19=4≤4 。持续时间为5,因此输出8 12
样例4
输入
11
16 17 18 19 20 21 22 21 22 24 26
输出
2 8