题
鸡哥最近正在制作一款游戏《狭道赛车手X》,他为游戏中的车辆编写了一个自动驾驶AI,使得游戏中的车辆的车辆能够在将要撞到别的车辆时自动绕过对方,且不需要减速。
然而游戏上线后鸡哥突然发现代码中存在一个bug,会让不同型号的车辆相遇时发生事故(追尾或者相撞) !
鸡哥希望能在玩家发现这个bug前推出一个《1.22热修复补丁》,否则游戏的评分就会非常难看。在他开始编写代码前,鸡哥想要知道玩家还要多久才能发现这个bug。一 旦有事故发生,玩家就会立刻发现这个bug。
鸡哥将每一辆车看做一条直线上的点,每辆车以(位置,速度,型号)这样的三元组给出。当型号相同的两辆车位于同一-坐标时,不会发生事故,但不同型号的两辆车位于同一坐标时,就会发生车祸。
鸡哥觉得这个任务非常简单,于是他将这个任务交给了你,为了给鸡哥一些时间来推送这个补J,你需要告诉鸡哥的时间是t:满足在[0, t]时间内没有发生事故,在(t,t + 1]的时间内发生了某起(或多起)事故。
Input
第一行有两个整数n,k(1 < k< n< 105),分别表示车辆的数量和不同型号的种数。
接下来的n行,第i行有三个整数p,v,t(-109 < P,V,< 109,1 < t < k),分别表示第i辆车的位置、速度和型号。
输入保证任意两辆车初始时不会在同一位置。
Output
在一行输出一个整数,表示你需要告诉鸡哥的时间 t。
特别地,如果永远不会有事故发生,输出 -1。
代码(二分)
#include "bits/stdc++.h"
using namespace std;
#define int long long
int n,k;
struct ppp
{
int p,v,t;
bool operator <(const ppp &z)const
{
if(p!=z.p)
return p<z.p;
return v<z.v;
}
}p[100009];
int fro[100009];
int nex[100009];
pair<int,int>q[100009];
int find(int time)
{
for(int i=1;i<=n;i++)
q[i]={p[i].p+p[i].v*time,i};
sort(q+1,q+n+1);
for(int i=1;i<=n;i++)
{
//相同位子 ,不同车型,代表碰撞
if(i!=n&&q[i].first==q[i+1].first&&p[q[i].second].t!=p[q[i+1].second].t)
return 0;
//上面这一步不能删掉,因为前面排序,即使位子相同也会是不同的 i
/*
如初始位子排序后 车型是 1 1 2
经过 x 秒后 第二个 车和第三个 车 位置相同
但排序后 车型 还是 1 1 2
按理说已经碰撞了 但下面 的 if(i<fro[q[i].second]||i>nex[q[i].second]) 检测不出来
所以需要上面的那个if语句
*/
//fro数组记录的是在不发生碰撞的情况下,可以到达的最前的位置 ,但你比最前位置还前就代表碰撞
//pre数组记录的是在不发生碰撞的情况下,可以到达的最后的位置 ,但你比最后位置还后就代表碰撞
if(i<fro[q[i].second]||i>nex[q[i].second])
return 0;
}
return 1;
}
signed main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>p[i].p>>p[i].v>>p[i].t;
sort(p+1,p+n+1);
for(int i=1;i<=n;i++)
{
//在不发生碰撞的情况下,可以到达的最前的位置
if(p[i].t==p[i-1].t)
fro[i]=fro[i-1];
else
fro[i]=i;
}
for(int i=n;i>=1;i--)
{
//在不发生碰撞的情况下,可以到达的最后的位置
if(p[i].t==p[i+1].t)
nex[i]=nex[i+1];
else
nex[i]=i;
}
//最大时间为-1e9 ~1e9 速度为1,所以r设为大于2e9即可,这里设为1e10
int l=0,r=1e10;
while(l!=r)
{
int mid=(l+r+1)/2;
if(find(mid))
l=mid;
else
r=mid-1;
}
if(r==1e10)
cout<<"-1";
else
cout<<r;
}
代码
#include "bits/stdc++.h"
using namespace std;
#define int long long
int n,k;
struct ppp
{
int p,v,t;
bool operator <(const ppp &z)const
{
return p<z.p;
}
}p[100009];
int fro[100009];
int nex[100009];
signed main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>p[i].p>>p[i].v>>p[i].t;
sort(p+1,p+n+1);
int position=1;
//记录前面离该车最近的不同车型
for(int i=2;i<=n;i++)
{
if(p[i].t!=p[i-1].t)
position=i-1;
fro[i]=position;
}
position=n;
//记录后面离该车最近的不同车型
for(int i=n-1;i>=1;i--)
{
if(p[i].t!=p[i+1].t)
position=i+1;
nex[i]=position;
}
//最大时间为-1e9 ~1e9 速度为1,所以r设为大于2e9即可,这里设为1e10
int sum=1e10;
for(int i=2;i<=n;i++)
{
if(p[fro[i]].t!=p[i].t&&p[fro[i]].v>p[i].v)//车型不同 且前面车的速度大于后面车的速度
{
if((p[i].p-p[fro[i]].p)%(p[fro[i]].v-p[i].v)==0)//刚好整除 则-1
sum=min(sum,(p[i].p-p[fro[i]].p)/(p[fro[i]].v-p[i].v)-1);
else
sum=min(sum,(p[i].p-p[fro[i]].p)/(p[fro[i]].v-p[i].v));
}
}
for(int i=1;i<n;i++)
{
if(p[nex[i]].t!=p[i].t&&p[i].v>p[nex[i]].v)//车型不同 且前面车的速度大于后面车的速度
{
if((p[nex[i]].p-p[i].p)%(p[i].v-p[nex[i]].v)==0)//刚好整除 则-1
sum=min(sum,(p[nex[i]].p-p[i].p)/(p[i].v-p[nex[i]].v)-1);
else
sum=min(sum,(p[nex[i]].p-p[i].p)/(p[i].v-p[nex[i]].v));
}
}
if(sum==1e10)
cout<<"-1";
else
cout<<sum;
}