Codeforecs-1260D

                   D. A Game with Traps

题目大意:

有一条线,线上有k个陷阱,但是你可以走到r来除去这个陷阱,士兵的敏捷值小于这个陷阱的危险程度的会死在这个陷阱,现在给你一组士兵,问你t秒内最多可以将多少个士兵移动到终点

题目链接  :https://codeforces.com/contest/1260/problem/D

 

解题思路:先将士兵的敏捷值排序,然后二分士兵敏捷值的最小值,即可得出答案,

我们实际上应该如何将士兵带到老板那里? 实际上,可以影响小队的每个陷阱都可以视为一个区[li,ri],这样我们的小队就无法移动到li,直到我们移至ri并解除该陷阱的武装。 我们应该走过这三段路:第一次是在没有小队的情况下向前走以解除陷阱的武装,第二次是向后走以返回小队,第三次是与小队一起前进。 因此,我们必须花费的总时间可以计算为n + 1 + 2T,其中T是属于至少一个陷阱段的单位段的数量-可以使用事件处理算法或段联合来计算。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3e5+10;
int a[maxn];
vector<pair<pair<int,int>,int> >q;
int m,n,k,t;
bool judge(int x)
{
    if(x==0) return true;
    int ans=n+1,minn=a[m-x+1];
    int l=0,r=-1;
    for(int i=0;i<q.size();i++)
    {
        if(q[i].second>minn)
        {
              if(r<q[i].first.first)
              {
                ans+=2*(r-l+1);
                l=q[i].first.first;
                r=q[i].first.second;
              }
              else r=max(r,q[i].first.second);
        }
    }
    ans+=2*(r-l+1);
    if(ans<=t) return true;
    else return false;
}
int main()
{
    cin>>m>>n>>k>>t;
    for(int i=1;i<=m;i++) cin>>a[i];
    sort(a+1,a+1+m);
    for(int i=0;i<k;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        q.push_back(make_pair(make_pair(a,b),c));
       //cin>>q[i].first.first>>q[i].first.second>>q[i].second;
    }
    sort(q.begin(),q.end());
    int l=0,r=m,ans=0;
    while( l<=r )
    {
        int mid=(l+r)>>1;
        if( judge(mid) )
        {
             l=mid+1;
             ans=mid;
        }
        else r=mid-1;
    }
    cout<<ans<<endl;
    return 0;
}
题解
原文地址:https://www.cnblogs.com/tombraider-shadow/p/11965959.html