CF1467 C. Three Bags
题意:
有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); }
分类:
其他
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2018-10-19 致备战noip2018的勇士
2017-10-19 UVA 690 Pipeline Scheduling
2017-10-19 2017 国庆湖南 Day4
2017-10-19 2017 国庆湖南 Day5
2017-10-19 2017 国庆湖南 Day6
2017-10-19 2017国庆 清北学堂 北京综合强化班 Day1