题目链接: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了好几发,悲 :(
标签:std,数组,840,int,cin,abs,Another,Problem,cout From: https://www.cnblogs.com/ACMER-XiCen/p/17095064.html