題意:
n個人以不同的速度在環上順時針或逆時針移動,每次相遇,移除下標小的,問最後只剩下一個人的時間的分數形式
官方題解及思路:
也不是第一次寫循環鏈表的題了,還是寫了好久。。
注意維護循環鏈表時要同時更新左右指針
代碼:
#include<bits/stdc++.h>
const int N = 1e5+10;
using namespace std;
struct node{
double val;
int d,v,id,w,l;
node(){val=0;}
node(double a,int b,int c,int i=0,int _w=0,int _l=0){
val = a;d = b;v = c;id = i;w = _w;l = _l;
}bool operator <(const node& a)const {
return val > a.val;
}
}A[N];
bool cmp(node a,node b){
return a.d<b.d;
}
int n,l;
int R[N],L[N];
bool used[N];
priority_queue< node >Q;
node oper(int x,int y){
if(x==y)return node(0,0,0,0,x,y);
int d , v , w=A[x].id>A[y].id?x:y;
if(A[x].v>0){
if(A[y].v<=0){d = A[y].d - A[x].d;v = A[x].v - A[y].v;}
else {
if(A[y].v<A[x].v){d = A[y].d - A[x].d;v = A[x].v - A[y].v;}
else {d = l + A[x].d - A[y].d;v = A[y].v - A[x].v;}
}
}else {//A[x].v<=0
if(A[y].v>0){d = l + A[x].d - A[y].d;v = A[y].v - A[x].v;}
else {//A[y].v<=0
if(A[y].v>A[x].v){d = l + A[x].d - A[y].d;v = A[y].v - A[x].v;}
else {d = A[y].d - A[x].d;v = A[x].v - A[y].v;}
}
}
return node(1.0*d/v,d,v,0,w,x^y^w);
}
int main()
{
//freopen("1004.in","r",stdin);
//freopen("my_1004.out","w",stdout);
int T;
scanf("%d",&T);
while(T--){
while(!Q.empty())Q.pop();
scanf("%d%d",&n,&l);
memset(used,0,sizeof(used));
for(int i=0;i<n;i++)scanf("%d",&A[i].d),L[i]=i-1,R[i]=i+1,A[i].id=i;
for(int i=0;i<n;i++)scanf("%d",&A[i].v);R[n-1]=0,L[0]=n-1;
sort(A,A+n,cmp);
for(int i=0,j=1;i<n;i++){
if(j)Q.push(oper(i,j));
else Q.push(oper(j,i));
if(++j==n)j=0;
}node ans ;
while(!Q.empty()){
node tmp = Q.top();Q.pop();
if(tmp.w==tmp.l)break;
if(used[tmp.w]||used[tmp.l])continue;
if(tmp.val>ans.val)ans = tmp;
used[tmp.l]=true;
int y,x=tmp.w;
if(L[tmp.w]==tmp.l){
y = L[x];
while(used[y])y=L[y];
L[x] = y;R[y] = x;
}else if(R[tmp.w]==tmp.l){
y = R[x];
while(used[y])y=R[y];
R[x] = y;L[y] = x;
}if(x>y)swap(x,y);
Q.push(oper(x,y));
}int gcd = __gcd(ans.d,ans.v);
printf("%d/%d\n",ans.d/gcd,ans.v/gcd);
}return 0;
}