标签:end 排列 pac with 直接 const 记录 否则 ons
题目大意:
一共有m个士兵,k个陷阱,时间为t,一个首领,这个首领需要在t时间内尽可能多的将士兵带到boos的面前, 第二行是每个士兵的灵敏度。
紧接着是k个陷阱,每个陷阱有l,,r,,d组成,l代表陷阱的位置,r代表l处的陷阱可以在位置r处被解决,陷阱的灵敏度是d,当陷阱的灵敏度比士兵的灵敏度大时,则可以杀掉士兵。陷阱对首领没有用。
问首领最多可以将多少名士兵带到boos的面前。
题解:二分+贪心。
首先根据这些士兵的灵敏度,从高到低进行排序,然后二分取第x灵敏度的士兵记为mi,然后将陷阱灵敏度大于mi的陷阱挑出来。接下来就是暴力模拟。将这些陷阱按照 l 升序排列。然后我们记录一下当前的士兵的位置。
如果说陷阱消除位置比士兵当前位置小,那么说明此陷阱已经被消除了,不用考虑。否则,我们需要首领带着士兵走到当前陷阱的位置l-1处,然后首领在去消除陷阱。陷阱消除位置一定在l的右侧,也就说
小于r的所以陷阱都已经被消除了。直接让arrive=l-1;
最后在ans=ans*2+n+1;
因为首领消除陷阱需要往返。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll N=2E5+7; const ll INF=1e9+7; ll n,m,k,t; ll arr[N]; bool cmp(const ll &x,const ll &y) { return x>y; } struct stu{ ll l,r,d; }trap[N]; stu c[N]; bool cmp2(const stu &x,const stu &y){ return x.l<y.l; } bool check(ll x){ ll mi=arr[x]; ll pos=0; for(ll i=1;i<=k;i++){ if(trap[i].d>mi) { c[pos++]=trap[i]; } } ll arrive=0; ll time=0; sort(c,c+pos,cmp2); for(ll i=0;i<pos;i++){ if(c[i].r<=arrive) continue; arrive=max(arrive,c[i].l-1); time+=c[i].r-arrive; arrive=c[i].r; } time=n+1+time*2; return time<=t; } int main(){ ios::sync_with_stdio(0); cin>>m>>n>>k>>t; for(ll i=1;i<=m;i++) cin>>arr[i]; sort(arr+1,arr+1+m,cmp); for(ll i=1;i<=k;i++) cin>>trap[i].l>>trap[i].r>>trap[i].d; ll left=0; arr[0]=INF; ll right=m,ans=0; while(right>=left){ ll mid=(left+right)/2; if(check(mid)){ ans=max(ans,mid); left=mid+1; } else right=mid-1; } cout<<ans<<endl; return 0; }
D - A Game with Traps-- codeforces 1260D A
标签:end 排列 pac with 直接 const 记录 否则 ons
原文地址:https://www.cnblogs.com/Accepting/p/12041553.html