解题报告:HDU_6136:Death Podracing (优先队列+循环链表)

来源:互联网 发布:本地数据库搭建 编辑:程序博客网 时间:2024/05/18 13:46

题目链接

题意:

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;}