1 条题解
-
0
自动搬运
来自洛谷,原作者为

GeorgeAAAADHD
will AFO搬运于
2025-08-24 22:34:00,当前版本为作者最后更新于2023-03-23 12:41:43,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
注:本题作者使用二分算法。
感谢
https://www.luogu.com.cn/user/909294大错误。
题目大意:
给定 和 个正整数 ,你需要输出两个数字 和 。
总共执行 次操作,当这次操作为第奇数次操作时,在所有 中找到一个最大但不超过 的 ,加上它并将它删去。如果所有 均大于 ,将 加上最小的 并将这个 删去。如果这次操作是第偶数次操作,则对 执行同样的操作。
数据范围:,。
分析:
暴力枚举是 算法,肯定超时。
于是我们思考一下二分的做法。
发现将 升序排序后,可以利用二分查找最大但不超过 或 的 。注意排序时应写成
sort(a.begin(),a.end());。然后我们用一个
vector存储所有 ,动态维护这个vector,每次操作后将要删除的 删除就可以了。这个地方需要用到iterator,即迭代器,可以自行上网搜索。于是我们便愉快地 AC 了本题。
注: 和 的最终结果有可能会超过
int范围,因此我们要开long long。Code:
#include<bits/stdc++.h> using namespace std; long long n,suma=0,sumb=0,k; bool f=1; vector<long long> a; void add(long long &sum){ int l=0,r=a.size()-1,ans=0,x=0; while(l<=r){ int mid=(l+r)/2; if(a[mid]<=sum){ x=mid; ans=a[mid]; l=mid+1; } else r=mid-1; } if(!ans){ sum+=a[0]; a.erase(a.begin()); } else{ sum+=a[x]; a.erase(a.begin()+x); } } int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>k; a.push_back(k); } sort(a.begin(),a.end()); for(int i=1;i<=n;i++){ if(f)add(suma); else add(sumb); f=!f; } cout<<suma<<' '<<sumb; }
- 1
信息
- ID
- 8483
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者