http://acm.hdu.edu.cn/showproblem.php?pid=6136
题目大意:在一个长为L的操场里有n个人,每个人都有一个起点和一个初速度。如果有两个人在操场上相遇了那么编号小的那个人就出局了。问最后还剩下一个人用时是多少???
解题思路:对于初始点的位置进行排序,一个点最早相遇的点就是就是它的左右相邻的点,队列按照相遇时间最小进行优先,然后不断的更新与该点左右相邻的点并将其放入优先队列中。对于已经查询过的点进行标记避免出现了重复查询的情况。
AC代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <map> 5 #include <vector> 6 #include <bits/stdc++.h> 7 using namespace std; 8 const int maxn=1e5*2+5; 9 struct neart 10 { 11 int now,next; 12 double time; 13 neart(int l=0,int r=0,double t=0.0) 14 { 15 now=l,next=r,time=t; 16 } 17 bool operator < (const neart &a) const 18 { 19 return time>a.time; 20 } 21 }; 22 priority_queue<neart>que; 23 struct node 24 { 25 int st,sp,id; 26 } a[maxn]; 27 int L[maxn],R[maxn],l,n,m,all,vis[maxn]; 28 int cmp(const node &a,const node &b) 29 { 30 return a.st<b.st; 31 } 32 int gcd(int x,int y) 33 { 34 if(y==0) return x; 35 else return gcd(y,x%y); 36 } 37 double get_t(int x,int y) 38 { 39 int len=((a[y].st-a[x].st)+l)%l; 40 int d=(a[x].sp-a[y].sp); 41 if(d<0) 42 { 43 d=-d,len=l-len; 44 } 45 return 1.0*len/d; 46 } 47 void output(int x,int y) 48 { 49 int len=((a[y].st-a[x].st)+l)%l; 50 int d=(a[x].sp-a[y].sp); 51 if(d<0) 52 { 53 d=-d,len=l-len; 54 } 55 int g=gcd(len,d); 56 printf("%d/%d ",len/g,d/g); 57 } 58 int main() 59 { 60 int eps; 61 //freopen("1004.in","r",stdin); 62 scanf("%d",&eps); 63 while(eps--) 64 { 65 scanf("%d%d",&n,&l); 66 for(int i=0; i<n; i++) 67 { 68 scanf("%d",&a[i].st); 69 a[i].id=i; 70 } 71 for(int i=0; i<n; i++) 72 scanf("%d",&a[i].sp); 73 74 sort(a,a+n,cmp); 75 while(!que.empty()) 76 que.pop(); 77 for(int i=0; i<n; i++) 78 { 79 double t=get_t(i,(i+1)%n); 80 que.push(neart(i,(i+1)%n,t)); 81 L[i]=((i-1)+n)%n; 82 R[i]=(i+1)%n; 83 } 84 all=n; 85 neart p; 86 memset(vis,0,sizeof(vis)); 87 while(que.size()>1) 88 { 89 p=que.top(); 90 que.pop(); 91 int p1=p.now; 92 int p2=p.next; 93 if(vis[p1]==1||vis[p2]==1) continue; 94 if(L[p1]==p2&&R[p1]==p2) break; 95 if(a[p1].id>a[p2].id) 96 { 97 vis[p2]=1; 98 R[p1]=R[p2]; 99 L[R[p2]]=p1; 100 double t=get_t(p1,R[p2]); 101 que.push(neart(p1,R[p2],t)); 102 } 103 else 104 { 105 vis[p1]=1; 106 L[p2]=L[p1]; 107 R[L[p1]]=p2; 108 double t=get_t(L[p1],p2); 109 que.push(neart(L[p1],p2,t)); 110 } 111 if(--all<=0) break; 112 } 113 p=que.top(); 114 int p1=p.now; 115 int p2=p.next; 116 output(p1,p2); 117 } 118 return 0; 119 }