解題報告:HDU_6136:Death Podracing (優先隊列+循環鏈表)

題目鏈接

題意:

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章