D. A Game with Traps - (二分+前缀和)集训补题
作者:互联网
D. A Game with Traps
https://codeforces.com/contest/1260/problem/D
思路
又是奇妙的二分。
题意为你需要带领士兵(从0点出发)去见老板(位于n+1),士兵不能单独行动只能由你带领他们一起行动,路上会存在很多陷阱,当某个士兵的灵敏度小于陷阱的d时,该士兵会死掉,求出可以带领士兵安全到达老板处的最大数量。
二分求出最大值即可。
考虑最小用时的计算:
- 尽可能使被选择士兵中的最小灵敏度变大。
- 合并有重合值的区间,因为如果多个陷阱存在重复值如果单个走会重复计算重复值部分,会使答案偏大,因此最优方案为走完合并后的区间的总用时。
- 前缀和,将陷阱的起点标记,在陷阱的终点后一位置取消标记,计算前缀和并判断每个位置的标志值,假如被标记则该点需要走3次,(你需要走过去消除陷阱,再回去接上士兵,最后一起走过去),如果没被标记则加1即可。
Code
#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
const int N=2e5+7;
const ll mod=998244353;
struct $
{
int l,r,x;
bool operator < ($ p)const{
if(l!=p.l)return l<p.l;
else if(r!=p.r)return r>p.r;
else return x<p.x;
}
}a[N];
int b[N];
map<int,int>mp;
int n,m,k,t;
bool cmp(int x,int y){return x>y;}
bool check(int x){
for (int i = 0; i <= n+1; ++i)
{
mp[i]=0;
}
for (int i = 0; i < k; ++i)
{
if(a[i].x>x){
mp[a[i].l]++;
mp[a[i].r+1]--;
}
}
int sum=0,cnt=0;
for (int i = 1; i <= n+1; ++i)
{
sum+=mp[i];
if(sum)cnt+=3;
else cnt++;
}
if(cnt>t)return false;
else return true;
}
int main(){
IO;
int T=1;
//cin>>T;
while(T--){
cin>>m>>n>>k>>t;
for (int i = 1; i <= m; ++i)
{
cin>>b[i];
}sort(b+1,b+m+1,cmp);
for (int i = 0; i < k; ++i)
{
cin>>a[i].l>>a[i].r>>a[i].x;
}
int l=0,r=m;
b[0]=inf;
int ans=0;
while(l<=r){
int mid=(l+r)>>1;
int x=b[mid];
if(check(x)){
ans=mid;
l=mid+1;
}
else
r=mid-1;
}cout<<ans<<endl;
}
return 0;
}
标签:return,Traps,int,cin,mid,Game,补题,陷阱,const 来源: https://www.cnblogs.com/KeepInCode/p/14352355.html