题目链接:Codeforces - Mike and distribution
此题可以随机化,比较玄学。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10;
std::mt19937 rnd(time(0));
int n,k,flag,a[N],b[N],p[N]; long long sa,sb;
signed main(){
cin>>n; k=n/2+1;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),sa+=a[i],p[i]=i;
for(int i=1;i<=n;i++) scanf("%d",&b[i]),sb+=b[i];
while(!flag){
shuffle(p+1,p+1+n,rnd); long long s1=0,s2=0;
for(int i=1;i<=k;i++){
s1+=a[p[i]],s2+=b[p[i]];
if(s1>sa/2&&s2>sb/2){flag=1; break;}
}
}
cout<<k<<endl;
for(int i=1;i<=k;i++) printf("%d ",p[i]);
return 0;
}
正解:
我们按照a从大到小排序。
然后看相邻的两个b,取大的一个,那么必然合法。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10;
int n,k;
struct node{int a,b,id;}t[N];
int cmp(node s1,node s2){return s1.a>s2.a;}
signed main(){
cin>>n; k=n/2+1;
for(int i=1;i<=n;i++) scanf("%d",&t[i].a),t[i].id=i;
for(int i=1;i<=n;i++) scanf("%d",&t[i].b);
sort(t+1,t+1+n,cmp);
printf("%d\n%d",k,t[1].id);
for(int i=2;i<=n;i+=2)
if(t[i+1].b>t[i].b) printf(" %d",t[i+1].id);
else printf(" %d",t[i].id);
return 0;
}