H. 雞哥的 AI 駕駛 題解(二分+思維)


題目鏈接

題目思路

容易想到本題要求的最晚安全時間可以用二分的方式尋找。

對於兩種不同型號的車,如果他們的相對位置發生了改變,那么就發生了碰撞。

因此,每輛車移動的最大范圍就是他兩邊相同型號車的范圍。

這句話的意思就是最開始按照位置排完序之后現在型號為 1 1 2 2 2 1 1

那么前兩個車可以隨意位置

第3-第5個車可以隨意位置

最后兩個車可以隨意位置

二分時間,按新位置排序,如果某個時間有車輛超出了它的最大移動范圍,那么就發

生了碰撞,這個檢查可以在 \(O(n logn)\) 的時間內完成。

當然還有許多其他的方法來進行 check。

check的時候要注意相等坐標的情況要特判

復雜度:\(O(n log^2n)\)

代碼

#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=2e5+5,inf=0x3f3f3f3f,mod=998244353,lim=300;
const double eps=1e-6;
int n,k;
int l[maxn],r[maxn];
pair<ll,int> pa[maxn];
struct node{
    int p,v,t,id;
}a[maxn];
bool cmp(node a,node b){
    return a.p<b.p;
}
bool check(ll x){
    for(int i=1;i<=n;i++){
        pa[i]={a[i].p+a[i].v*x,i};
    }
    sort(pa+1,pa+1+n);
    for(int i=1;i<=n;i++){
        if(i!=1&&pa[i].fi==pa[i-1].fi&&pa[i].se!=pa[i-1].se) return 0;
        if(l[pa[i].se]>i||i>r[pa[i].se]) return 0;
    }
    return 1;
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>a[i].p>>a[i].v>>a[i].t;
        a[i].id=i;
    }
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++){
        if(a[i].t==a[i-1].t){
            l[i]=l[i-1];
        }else{
            l[i]=i;
        }
    }
    for(int i=n;i>=1;i--){
        if(a[i].t==a[i+1].t){
            r[i]=r[i+1];
        }else{
            r[i]=i;
        }
    }
    ll l=0,r=1e10,ans=-1;
    while(l<=r){
        ll mid=(l+r)/2;
        if(check(mid)){
            l=mid+1;
            ans=mid;
        }else{
            r=mid-1;
        }
    }
    if(ans==1e10) ans=-1;
    cout<<ans;
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM