Codeforces Round #786 (Div. 3)(E) Breaking the Wall 题解

原题链接

#include<iostream>
#include<math.h>
#include<algorithm>

using namespace std;
int a[200005];

int main() {
    int n;
    cin >> n;
    int res = 1000000;

    for (int i = 1; i <= n; i++)
        cin >> a[i];
    // x操作: 即每次将该数字a减去x大小,求将a变为0的操作次数
    
    //情况1. 对i 和 i+1 进行2操作,求i和i+1的数字变为0的最少操作数
    // a. 当 a[i]远大于a[i+1]时, a[i]>2*a[i+1] 时, 对 i 进行 2操作 (a[i]+1)/2 次 后,即可把 i和i+1变为 0
    // b. 当 a[i+1]>2*a[i]时, 同上
    // c. 当 a[i]和a[i+1]不满足上述两种条件, 即a[i]和a[i+1]大小接近,只对其中一个数字进行2操作无法使这两个数字都变为0
    //      需要对i和i+1都进行2操作,因为对其中一个数进行2操作时,会对另一个数进行1操作,
    //      所以我们可以将其看成对两个数之和进行3操作,然后向上取整,即 (a[i]+a[i+1]+2 )/3
    for (int i = 1; i < n; i++)
        res = min(res, max(max((a[i] + 1) / 2, (a[i + 1] + 1) / 2), (a[i] + a[i + 1] + 2) / 3));

    //情况2. 把i+1和i-1变为0 , 求最少操作数
    //这种情况因为i远大于i-1 和 i+1,所以只能选择把i-1 和 i+1变为0,
    //所以第一步先对i进行2操作,即对i-1 和 i+1 的进行1操作,其中的最小值会先为0,然后对剩下的非0数进行2操作就是结果
    for (int i = 2; i < n; i++)
        res = min(res,(min(a[i - 1], a[i + 1]) + (abs(a[i - 1] - a[i + 1]) + 1) / 2));

    //情况3. 把a中的最小的两2数进行2操作
    sort(a + 1, a + n + 1);
    res = min(res, (a[1]+1)/2+(a[2]+1)/2);

    cout << res << endl;
}
posted @ 2022-09-05 16:32  takeay  阅读(30)  评论(0)    收藏  举报