题解【CF798D Mike and distribution】

题目链接

思考方向:构造方法满足 A 的要求,再满足 B 的要求。

如果只考虑 A,有一种显然的方案:将 A 从大到小排序,选出前 n2+1 大的即可。但这样显然难以扩展,所以需要另寻方案。

由于题目提供了额外的 +1,所以先将最大的 A1 选上,对于剩下的 A2An,由于要满足二倍关系,不妨进行两两分组,即 A2,A3 一组,A4,A5 一组,依次类推。

这样会有一个结论:一组内任意选一个即可满足题目要求。

证明:
最坏的情况是,每组都选小的那个,即 A3,A5,A7...,那么最终总和(此处将选的数加上,不选的数减去,如果最终总和 >0,则说明满足题目条件)为:A1A2+A3A4+A5...An1+An,但是 A1>A2,A3>A4...,所以最后总和 >0,满足条件。

所以对于 A 的每一组内,只需要在 B 的对应下标选出比较大的数(反正 A 怎么选都行),一直下去就可以得出答案。

代码:

#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;
}
posted @   2017BeiJiang  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示