题意
一个长度为
L
的环形跑道上有
分析
将所有人按照所在位置排序后,最先相遇的人必然是相邻的两个人。所有人奔跑时速度不变,那么显然对于不相邻的人来说,他们相遇的时间可以通过初始的位置和速度求出。于是只需要模拟整个过程,使用优先队列处理最先相遇的两个点,每次删除一个点,当最后剩下两个人时,获取一下相遇时间即可。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
#define LL long long
#define MAXN 100100
const int mod=1e9+7;
struct Racer{
int d,v,power;
}rac[MAXN];
struct Node{
int a,b,d,v;
Node(){}
Node(int _a,int _b,int _d,int _v):a(_a),b(_b),d(_d),v(_v){}
};
int n,L;
int lef[MAXN];
int rig[MAXN];
int vis[MAXN];
bool cmp(Racer r1,Racer r2){
return r1.d<r2.d;
}
bool operator<(Node n1,Node n2){
return n1.d*1ll*n2.v>n2.d*1ll*n1.v;
}
int main(){
int T,res;
cin>>T;
while(T--){
scanf("%d %d",&n,&L);
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;++i){
if(i==1)
lef[i]=n;
else
lef[i]=i-1;
if(i==n)
rig[i]=1;
else
rig[i]=i+1;
}
for(int i=1;i<=n;++i){
scanf("%d",&rac[i].d);
rac[i].power=i;
}
for(int i=1;i<=n;++i)
scanf("%d",&rac[i].v);
sort(rac+1,rac+1+n,cmp);
res=n;
priority_queue<Node> q;
Node tmp;
for(int i=1;i<n;++i){
tmp.a=i;tmp.b=i+1;
tmp.d=rac[i+1].d-rac[i].d;
tmp.v=rac[i].v-rac[i+1].v;
if(tmp.v<0){
tmp.d=L-tmp.d;
tmp.v*=-1;
}
q.push(tmp);
}
tmp.a=n;tmp.b=1;
tmp.d=rac[1].d+L-rac[n].d;
tmp.v=rac[n].v-rac[1].v;
if(tmp.v<0){
tmp.d=L-tmp.d;
tmp.v*=-1;
}
q.push(tmp);
while(!q.empty()){
if(res==2)
break;
Node tp=q.top();
q.pop();
if(vis[tp.a] || vis[tp.b])
continue;
res--;
if(rac[tp.a].power<rac[tp.b].power){
vis[tp.a]=1;
rig[lef[tp.a]]=rig[tp.a];
lef[rig[tp.a]]=lef[tp.a];
tmp.a=lef[tp.b];tmp.b=tp.b;
tmp.d=rac[tmp.b].d-rac[tmp.a].d;
tmp.v=rac[tmp.a].v-rac[tmp.b].v;
if(tmp.d<0){
tmp.d*=-1;
tmp.v*=-1;
}
if(tmp.v<0){
tmp.d=L-tmp.d;
tmp.v*=-1;
}
q.push(tmp);
}
else{
vis[tp.b]=1;
rig[lef[tp.b]]=rig[tp.b];
lef[rig[tp.b]]=lef[tp.b];
tmp.a=tp.a;tmp.b=rig[tp.a];
tmp.d=rac[tmp.b].d-rac[tmp.a].d;
tmp.v=rac[tmp.a].v-rac[tmp.b].v;
if(tmp.d<0){
tmp.d*=-1;
tmp.v*=-1;
}
if(tmp.v<0){
tmp.d=L-tmp.d;
tmp.v*=-1;
}
q.push(tmp);
}
}
int ansm,anss,c;
while(!q.empty()){
tmp=q.top();
q.pop();
if(vis[tmp.a] || vis[tmp.b])
continue;
ansm=tmp.d;
anss=tmp.v;
break;
}
c=__gcd(ansm,anss);
ansm/=c;
anss/=c;
printf("%d/%d\n",ansm,anss);
}
}