Codeforces Round 901 (Div. 2) - B. Jellyfish and Game(思维 + 贪心)

选手A和选手B轮流进行k次操作:
1、把a数列中的一个值和b数列中的一个值进行交换
2、不进行任何操作

题目分为两种情况(结合代码看)
1、k为奇数:
(1) 如果a中最小值比b中最大值大,此时A不动。接下来不论选手B怎么拿,选手A总会回复原样
(2) 如果b中最大值比a中最小值大,此时A会拿b中最大的。接下来不论选手B怎么拿,选手A总会回复原样
2、k为偶数:
(1) 如果a中最小值仍大于b中最大值,此时A不动。但是此时B会拿走a中的最大值
(2) 如果a中最小值比b中最大值小,说明此时最优可以交换。 A把a中最小的(即min_a)和b中最大的(即max_b)交换后后。B会把此时b中最小的(即max(max_a,max_b))和此时a中最大的(即min(min_a,minb))交换

AC代码:

#include 
using namespace std;
#define ll long long
#define sf(x) scanf("%d", &x);
#define de(x) cout << x << " ";
#define Pu puts("");
const int N = 1e5 + 9, mod = 1e9 + 7;
ll a[N], b[N];
ll n, m, ans;
int main() {
    int T;
    cin >> T;
    ll k;
    // 存储a和b中的最大值、最小值
    ll max_a, min_a, max_b, min_b;
    while (T--) {
        cin >> n >> m >> k;
        max_a = max_b = 0;
        min_a = min_b = 1e9;
        ans = 0;
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            max_a = max(a[i], max_a);
            min_a = min(a[i], min_a);
            ans += a[i];
        }
        for (int i = 1; i <= m; i++) {
            cin >> b[i];
            max_b = max(b[i], max_b);
            min_b = min(b[i], min_b);
        }
        if (k % 2 == 0) {  // 如果k为偶数
            if (min_a >= max_b) {
                // 如果a中最小值仍大于b中最大值,此时A不动
                // 但是此时B会拿走a中的最大值
                cout << (ans - max_a + min_b) << endl;
                // max_a为全局最大
            } else {
                // 如果a中最小值比b中最大值小,说明此时最优可以交换
                // (这一行注释不用看,之前的错误思路)但不论选手A怎么拿,选手B总会回复原样
                // A把a中最小的(即min_a)和b中最大的(即max_b)交换后后
                // B会把此时b中最小的(即max(max_a,max_b))和此时a中最大的(即min(min_a,minb))交换
                cout << (ans - min_a + max_b - max(max_a, max_b) + min(min_a, min_b)) << endl;
            }
        } else {
            if (min_a >= max_b) {
                // 如果a中最小值比b中最大值大,此时A不动
                // 接下来不论选手B怎么拿,选手A总会回复原样
                cout << ans << endl;
                // max_a为全局最大
            } else {
                // 如果b中最大值比a中最小值大,此时A会拿b中最大的
                // 接下来不论选手B怎么拿,选手A总会回复原样
                cout << (ans - min_a + max_b) << endl;
            }
        }
    }
    return 0;
}

你可能感兴趣的:(Codeforces,刷题+算法,#,思维+模拟,算法,数据结构)