CF1467 C. Three Bags

Problem - C - Codeforces

 

题意:

有3个集合,每个集合里有若干个数

你可以选2个来自不同集合的数x、y,然后让2个数同时减去x

经过若干次操作后,只剩下1个数

问剩下的这个数最大可以是多少

 

操作相当于把一个集合里的数变号,然后放到另一个集合中并与集合中的某个数相加

设集合A中有a[1] a[2] a[3],集合B中有b[1] b[2] b[3],集合C中有c[1] c[2] c[3]

假设我们现在把a[1]变号放到B里并和b[1]相加,会变为

a[2] a[3],b[1]-a[1] b[2] b[3],c[1] c[2] c[3]

把b[1]-a[1]变号放到C里并和c[1]相加,会变为

a[2] a[3],b[2] b[3],c[1]-b[1]+a[1] c[2] c[3]

这一步相当于a[1]是被第2次放,它又变回了正号

可以看出,一个数如果被放了奇数次是负号,偶数次是正号

一个数来回放只是符号改变,所以直接让每个数放<=2次即可(即放奇数次直接放去目标位置,放偶数次中间只中转一次)

因为最后要变为1个数,所以必然存在1个数他被放了1次,这个数是负号

我们选这个数为3个集合里最小的数x

除了这个x所在集合,其余2个集合的数都可以在x中转一次,从而最终是正号

对于x所在集合的其他数,要么再在另外2个集合选最小的数作为中转,从而最终为正好;要么和x一样直接去最终位置,最终为负号

所以最终的答案是以下6种中最大的

1、总和-2*集合1的和

2、总和-2*集合2的和

3、总和-2*集合3的和

4、总和-2*(集合1最小数+集合2最小数)

5、总和-2*(集合1最小数+集合3最小数)

6、总和-2*(集合2最小数+集合3最小数)

 

#include<bits/stdc++.h>
 
using namespace std;
 
#define N 300003
 
int a[4][N];
 
int main()
{
    int n[4];
    for(int i=1;i<=3;++i) scanf("%d",&n[i]);
    long long tot[4]={0,0,0,0},mi,ans;
    for(int i=1;i<=3;++i)
    {
        for(int j=1;j<=n[i];++j)
        {
            scanf("%d",&a[i][j]);
            tot[i]+=a[i][j];
        }
        sort(a[i]+1,a[i]+n[i]+1);
    }
    mi=a[1][1]+a[2][1];
    mi=min(mi,min((long long)a[1][1]+a[3][1],(long long)a[2][1]+a[3][1]));
    mi=min(min(min(tot[1],tot[2]),tot[3]),mi);
    ans=tot[1]+tot[2]+tot[3]-mi-mi;
    printf("%lld",ans);
}

 

posted @ 2021-10-19 17:04  TRTTG  阅读(31)  评论(0编辑  收藏  举报