1 条题解

  • 0
    @ 2026-6-19 10:30:43

    📝 题目大意

    给定长度为 NN 的序列 AA 和区间 [L,R][L, R],对每个 AiA_i 找出区间内最接近 AiA_i 的整数 XiX_i(即 XiAi|X_i - A_i| 最小)。若 AiA_i 落在区间内,则 Xi=AiX_i = A_i;否则取较近的端点。

    💡 解题思路

    1. 题目分析N2×105N \le 2 \times 10^5Ai,L,R109A_i, L, R \le 10^9,直接 O(N)O(N) 即可。问题本质是对每个 AiA_i 做一次 clamp 操作,将其限制在 [L,R][L, R] 内。
    2. 算法推导
      • 对于每个 AiA_i,考虑三种情况:
        • Ai<LA_i < L:区间内所有值都大于 AiA_i,最近的显然是左端点 LL
        • Ai>RA_i > R:区间内所有值都小于 AiA_i,最近的显然是右端点 RR
        • LAiRL \le A_i \le RAiA_i 本身就在区间内,距离为 00,取 Xi=AiX_i = A_i
      • 因此只需对每个 AiA_i 执行 clamp(A_i, L, R)
    3. 边界与细节
      • L=RL = R 时区间退化为一个点,答案全为 LL(或 RR),逻辑依然正确。
      • 注意输出格式:末尾换行,元素间空格分隔。

    ⏱️ 复杂度分析

    • 时间复杂度O(N)O(N),每个元素 O(1)O(1) 处理。
    • 空间复杂度O(1)O(1),只需几个变量。

    💻 标准代码 (C++)

    #include <iostream>
    #include <algorithm>
    using namespace std;
    int main() {
        int N, L, R;
        cin >> N >> L >> R;
        for (int i = 0; i < N; i++) {
            int A;
            cin >> A;
            // 将 A 限制在 [L, R] 区间内
            int x;
            if (A < L) x = L;       // A 在区间左侧,取左端点
            else if (A > R) x = R;  // A 在区间右侧,取右端点
            else x = A;             // A 在区间内,取自身
            cout << x << (i == N - 1 ? "\n" : " ");  // 输出,末尾换行
        }
        return 0;
    }
    
    • 1

    信息

    ID
    752
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者