牛客小白月赛66 F
思路:我们能够发现如果ai>aj且aj可以满足条件,那么ai一定可以满足条件,假设除ai,aj外的其他的所有的碰撞得到的最小的大小是k,那么如果有aj可以满足条件,那么有(ai+k)/2<=aj,则能够得到k<=2*aj-ai,那么对于(aj+k)/2<=(aj+2*aj-ai)/2=aj+(aj-ai)/2,因为ai>aj,则这个值一定小于等于ai,这样就证明了小的成立大的一定成立,然后怎样的到最小值呢,也可以证明从最大的往最小的按照题中的思路做,得到的就是最小值,假设a,b<c,那么((a+b)/2+c)/2--->(a+b+2*c)/4,如果是((a+c)/2+b)/2-->(a+c+2*b)/4,因为a<b<c则能够看出来第二个更小,所以先做大的得到的是最小的,那么我们只需要二分一下能够最小的到的,然后check一下即可
#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
const int N=1e5+7;
typedef pair<int,int> PII;
int n;
PII w[N];
int ans[N];
bool check(int mid) {
int res=-1;
for(int i=n;i>=1;i--) {
if(i==mid) continue;
if(res==-1) res=w[i].fi;
else res=(res+w[i].fi)/2;
}
if(res<=w[mid].fi) return true;
else return false;
}
int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&w[i].fi),w[i].se=i;
sort(w+1,w+1+n);
int l=1,r=n;
while(l<r) {
int mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
for(int i=l;i<=n;i++) ans[w[i].se]=1;
for(int i=1;i<=n;i++) printf("%d",ans[i]);
return 0;
}