題目鏈接
題目思路
容易想到本題要求的最晚安全時間可以用二分的方式尋找。
對於兩種不同型號的車,如果他們的相對位置發生了改變,那么就發生了碰撞。
因此,每輛車移動的最大范圍就是他兩邊相同型號車的范圍。
這句話的意思就是最開始按照位置排完序之后現在型號為 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;
}