zoukankan      html  css  js  c++  java
  • 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);
    }
    作者:xxy
    本文版权归作者和博客园共有,转载请用链接,请勿原文转载,Thanks♪(・ω・)ノ。
  • 相关阅读:
    排序算法——选择排序
    poj1906
    poj1496
    poj1244
    poj1183
    poj1806
    !!!舒尔茨自律神经训练法
    Google Analytics的能与不能
    乔布斯最伟大的贡献是什么
    冥想呼吸
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/15425530.html
Copyright © 2011-2022 走看看