题解【CF798D Mike and distribution】
思考方向:构造方法满足 的要求,再满足 的要求。
如果只考虑 ,有一种显然的方案:将 从大到小排序,选出前 大的即可。但这样显然难以扩展,所以需要另寻方案。
由于题目提供了额外的 ,所以先将最大的 选上,对于剩下的 ,由于要满足二倍关系,不妨进行两两分组,即 一组, 一组,依次类推。
这样会有一个结论:一组内任意选一个即可满足题目要求。
证明:
最坏的情况是,每组都选小的那个,即 ,那么最终总和(此处将选的数加上,不选的数减去,如果最终总和 ,则说明满足题目条件)为:,但是 ,所以最后总和 ,满足条件。
所以对于 的每一组内,只需要在 的对应下标选出比较大的数(反正 怎么选都行),一直下去就可以得出答案。
代码:
#include<bits/stdc++.h> using namespace std; const int N=1e5+10; int n; struct node { int a,b,id; }s[N]; int cmp(node x,node y) { if(x.a!=y.a) return x.a>y.a; else return x.b>y.b; } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>n; for(int i=1;i<=n;i++) { cin>>s[i].a; s[i].id=i; } for(int i=1;i<=n;i++) cin>>s[i].b; sort(s+1,s+1+n,cmp); int st=0; vector<int> ans; if(n%2==0) { st=3; ans.push_back(s[1].id); ans.push_back(s[2].id); } else { st=2; ans.push_back(s[1].id); } for(;st<=n;st+=2) { if(s[st].b>s[st+1].b) ans.push_back(s[st].id); else ans.push_back(s[st+1].id); } sort(ans.begin(),ans.end()); cout<<ans.size()<<endl; for(int a:ans) cout<<a<<" "; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效