zoukankan      html  css  js  c++  java
  • 【Codeforces Round #695 (Div. 2) C】Three Bags

    题目链接

    链接

    翻译

    给你 (3) 个多重集,第 (i) 个集合有 (n[i]) 个数字。

    从两个不同集合中分别取出数字 (x)(y),则从两个集合中分别删去 (x)(y), 然后在第 (1) 个集合中(取出 (x)

    的那个集合) 加入元素 (x-y)

    要求最后只有一个集合中剩下一个数字,问你这个数字最大可以是多少。

    题解

    思维

    把操作 ((x,y)) 看做是有向树的一条边,边由儿子节点指向父节点,其中儿子节点表示 (y),父节点表示 (x)

    即操作过后, 儿子节点没了,父节点变成 (x-y),直到只剩下一个根节点为止。

    那么,形成的这棵树有 (n_1+n_2+n_3) 个节点。

    模拟一下会发现,最后剩下的一个数字就为树中偶数层的节点之和减去奇数层的节点之和(根视为第 (0) 层)。

    问题就转化成让奇数层上数字之和最小。

    但是奇数层上的数字是有限制的,会发现奇数层上的节点要满足以下两个条件之一:

    • 1.奇数层上的节点全都来自同一个集合 (X) 中,且这个集合 (X) 中的全部元素都在奇数层上。
    • 2.奇数层上的节点来自至少两个集合中的数字。

    证明如下: 如果奇数层上的节点全都来自同一个集合 (X) ,但是没有包括 (X) 中的全部元素的话,那么 (X)

    中剩下的元素怎么办?只能放在偶数层了,但是这就和题目中的操作冲突了,因为这个偶数层的节点会和奇数层

    的来自同一集合中的元素进行合并操作了,非法。所以只能全都在同一层。

    而如果奇数层上的节点至少来自两个集合则没有这个烦恼了,父节点是相同集合的元素的话,就全都扔在另外一个

    集合的节点下面就好了。

    这样的话,我们就最多用一个 (3) 层的如上所述的树就能完成构造了,奇数层就是第 (1) 层,可以是两个集合中各自

    最小的元素的加和,或者全都来自同一个集合中的数字的加和。排个序,考虑一下这几种情况就好。

    代码

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    
    const int N = 3e5;
    
    int n[4];
    int a[4][N + 10];
    
    int main() {
    #ifdef LOCAL_DEFINE
    	freopen("in.txt", "r", stdin);
    #endif
    	ios::sync_with_stdio(0), cin.tie(0);
    	for (int i = 1; i <= 3; i++) {
    		cin >> n[i];
    	}
    
    	for (int i = 1; i <= 3; i++) {
    		for (int j = 1; j <= n[i]; j++) {
    			cin >> a[i][j];
    		}
    		sort(a[i] + 1, a[i] + 1 + n[i]);
    	}
    
    	LL ans = 0;
    
    
    	LL temp1 = 0;
    	for (int i = 1; i <= 3; i++) {
    		for (int j = 1; j <= n[i]; j++) {
    			temp1 += a[i][j];
    		}
    	}
    
    	//1.奇数层全都来自同一个bag
    	for (int i = 1; i <= 3; i++) {
    		LL temp2 = 0;
    		for (int j = 1;j <= n[i];j++){
    			temp2 += a[i][j];
    		}
    		ans = max(ans, temp1 - 2 * temp2);
    	}
    
    	//1.奇数层来自两个不同的bag
    	for (int i = 1; i <= 3; i++) {
    		LL temp2 = 0;
    		//1,2
    		temp2 = a[1][1] + a[2][1];
    		ans = max(ans, temp1 - 2 * temp2);
    
    		//1,3
    		temp2 = a[1][1] + a[3][1];
    		ans = max(ans, temp1 - 2 * temp2);
    
    		//2,3
    		temp2 = a[2][1] + a[3][1];
    		ans = max(ans, temp1 - 2 * temp2);
    	}
    	cout << ans << endl;
    	return 0;
    }
    
  • 相关阅读:
    字符串的不可变性--转载
    this的作用--转载
    构造函数
    根基决定一个程序员会不会被淘汰 --转载
    BAT-使用BAT方法清理Delphi临时文件
    键盘,鼠标,文件
    画布.画笔.画刷
    Delphi外挂开发网站
    教程-经典Delphi教程网
    教程-Delphi各版本与工具下载地址
  • 原文地址:https://www.cnblogs.com/AWCXV/p/14254240.html
Copyright © 2011-2022 走看看