Codeforces Round #840 (Div. 2) and Enigma 2022 - Cybros LNMIIT C. Another Array Problem(贪心,思维)

题目链接:https://codeforces.com/problemset/problem/1763/C

 

 

 大致题意:  给你长度为n的数组,你可以进行任意次操作,操作内容如下:

      选择俩个下标i,j;对于i到j之间的所有数,将他们变成abs(ai-aj);

      问,在进行以上操作后,数组的总和最大可以是多少?

 

解题思路:我们观察这个操作,不难发现,如果ai和aj其中一个是0,对于数组的总和来说,是比较好的一种情况;

     进一步想,如果ai是最大,aj是0,那么对于i到j区间的变化来说,是最优的;

     对于一个数组,最大值一定是有的,最小值却不一定是0,那么这个时候该怎么办?

     我们可以发现,如果ai和aj相同,那么进行操作后,i到j之间就变成了0;

     那么因为这个操作会让区间的数都相同,所以我们完全可以找到俩个数相同,进而使数组出现0;

     所以,对于n>=4的数组来说,其结果是最大值乘长度;(为什么是n>=4,读者可以思考一下);

     那么对于n==2和n==3的情况,完全可以分类讨论一下,也就是枚举结果;

那么这题就解决了,时间复杂度:O(n);

ac代码:

#include<bits/stdc++.h>
#define int long long

signed main()
{
    std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0);

    int T; std::cin >> T;
    while (T--)
    {
        int n; std::cin >> n;
        if (n == 2)
        {
            int x, y; std::cin >> x >> y;
            std::cout << std::max( x + y, 2 * abs(y - x)) << "\n";
            continue;
        }
        else if (n == 3)
        {
                        //个人此处写的比较shi,其实有比较好的方法的,读者可以思考一下;
            int x, y, z; std::cin >> x >> y >> z;
            int p1 = x + y + z, p2 = 2 * abs(y - x) + z;
            int p3 = 2 * abs(z - y) + x, p4 = 3 * abs(z - x);
            int p5 = abs(y - x) + 2 * abs(abs(y - x) - z);
            int p6 = abs(y - z) + 2 * abs(abs(y - z) - x);
            int p7 = 3 * z, p8 = 3 * x;
            int p9 = 3 * abs(y - z), p10 = 3 * abs(y - x);
            std::cout << std::max({ p1,p2,p3,p4,p5,p6,p7,p8,p9,p10 }) << "\n";
            continue;
        }
        std::vector<int> nums(n + 1, 0);
        for (int i = 1; i <= n; ++i)
            std::cin >> nums[i];
        int mx = *max_element(nums.begin(), nums.end());
        int ans = mx * n;
        std::cout << ans << "\n";
    }

    return 0;
}    

这题主要是对于思维能力以及分类讨论的能力的考查,其实思维相对来说还是比较简单的,就是对于n==3的情况,有没有考虑完全(因为考虑不完全,wa了好几发,悲 :(

posted @ 2023-02-06 12:47  XiCen  阅读(43)  评论(0)    收藏  举报