1 条题解

  • 0
    @ 2026-6-19 10:31:07

    📝 题目大意

    给定三个整数 A1,A2,A3A_1, A_2, A_3,每次操作可以选择任意一个元素加 11。求最少操作次数,使得三者构成等差数列,即 A2A1=A3A2A_2 - A_1 = A_3 - A_2

    💡 解题思路

    1. 题目分析:数据范围 1Ai10151 \leq A_i \leq 10^{15},需要开 long long。只能增加元素,不能减少,这意味着我们只能通过"向上调整"来让两个差值相等。

    2. 算法推导: 令 d1=A2A1d_1 = A_2 - A_1d2=A3A2d_2 = A_3 - A_2。目标:使 d1=d2d_1 = d_2

      分析三种操作对差值的影响:

      • A1A_111d1d_1 减少 11d2d_2 不变。
      • A2A_211d1d_1 增加 11d2d_2 减少 11(一箭双雕)。
      • A3A_311d2d_2 增加 11d1d_1 不变。

      核心策略分三步:

      • 第一步(缩小差距):若 d2>d1d_2 > d_1,反复操作 A2A_2 可以同时让 d1d_1 增加、d2d_2 减少,每次操作代价 11 却能让差距 d2d1|d_2 - d_1| 缩小 22。因此最多可以做 (d2d1)/2\lfloor (d_2 - d_1) / 2 \rfloor 次,此时若差距为偶数则已平衡,若为奇数则 d2=d1+1d_2 = d_1 + 1
      • 第二步(奇数修正):若差距为奇数,再做一次 A2A_2 操作,d1d_1d2d_2 的大小关系互换,变为 d1=d2+1d_1 = d_2 + 1(即 d1>d2d_1 > d_2)。
      • 第三步(单向追赶):此时 d1d2d_1 \geq d_2。若 d1>d2d_1 > d_2,只能通过操作 A1A_1(让 d1d_1 减少)或 A3A_3(让 d2d_2 增加)来消除剩余差距,每次操作代价 11、差距减少 11,共需 d1d2d_1 - d_2 次。

      等价地,设 x2x_2 为操作 A2A_2 的次数,x1,x3x_1, x_3 为操作 A1,A3A_1, A_3 的次数,可推导出总操作次数 =d1d2+3x2= d_1 - d_2 + 3x_2。由于 d1d2d_1 - d_2 固定,只需最小化 x2x_2,约束为 x2(d2d1)/2x_2 \geq \lceil (d_2 - d_1) / 2 \rceil(当 d2>d1d_2 > d_1 时),否则 x2=0x_2 = 0。代入即可得到与上述三步一致的闭式解。

    3. 边界与细节

      • 差值可能为负数(如 A2<A1A_2 < A_1),代码中变量 ab 存储的就是 d1d_1d2d_2,直接参与运算,无需特殊处理。
      • 最终答案可能达到 101510^{15} 级别,必须使用 long long(64 位整数)。
      • d1=d2d_1 = d_2 时,答案直接为 00,三步策略均不触发,max(a-b, 0) 返回 00

    ⏱️ 复杂度分析

    • 时间复杂度O(1)O(1),仅涉及常数次算术运算和条件判断。
    • 空间复杂度O(1)O(1),只使用了几个 long long 变量,无额外数组或递归。

    💻 标准代码 (C++)

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
        long long a, b, c, ans = 0;   // a,b,c 对应 A1,A2,A3,ans 为答案
        cin >> a >> b >> c;
        a = b - a;                    // a 变为 d1 = A2 - A1
        b = c - b;                    // b 变为 d2 = A3 - A2
        if (b > a) {                  // 若 d2 > d1
            long long d = (b - a) / 2;// 计算可做的 A2++ 次数(整数除法向下取整)
            ans += d;                 // 累加操作次数
            a += d;                   // d1 增加 d
            b -= d;                   // d2 减少 d
        }
        if (b > a) {                  // 差距为奇数,仍差 1
            b--;                      // 再做一次 A2++:d2 减 1
            a++;                      //              d1 加 1
            ans++;                    // 操作次数 +1
        }
        ans += max(a - b, 0ll);       // 若 d1 > d2,通过 A1++ 或 A3++ 补齐差距
        cout << ans << endl;
    }
    
    • 1

    信息

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