鸡哥的 AI 驾驶 (Gym - 103186H)

鸡哥最近正在制作一款游戏《狭道赛车手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(inex[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;
	
}

你可能感兴趣的:(二分,算法)