hdu
来源:互联网 发布:中国国防数据 编辑:程序博客网 时间:2024/05/19 10:15
HDU - 6136
解法一
第一种解法比较直观,最初始状态环上有
于是我们可以用一个堆维护环上所有相邻人相遇的时间,从中取出最小值,就能找到第一个被淘汰的人,这个人删除后,原本不相邻的两个人就相邻了,同样求出他们的相遇时间,加入堆中,重复执行这一过程,直到找到最后一个被淘汰的人为止。算法复杂度
#include<bits/stdc++.h>#define list lllusing namespace std;const int MAXN = 1E5+10;int n,l;struct Car{ int d,v,i; friend bool operator < (const Car& a,const Car &b) { return a.d<b.d; }} car[MAXN];struct List{ int pre,next;} list[MAXN];void del(int i){ if(list[i].pre!=-1) list[list[i].pre].next=list[i].next; if(list[i].next!=2*n) list[list[i].next].pre=list[i].pre;}bool vis[MAXN];struct Status{ int a,b;//约定b是在a的顺时针方向上的,也就是速度的正方向 long long int d,v; friend bool operator < (const Status &a,const Status &b) { return a.d*b.v>b.d*a.v; }};struct Fenshu{ long long int fenzi,fenmu; void reduce() { long long int gcd = __gcd(fenzi,fenmu); fenzi/=gcd; fenmu/=gcd; }};Status check(int a,int b){ Status status= {a,b}; status.d=car[b].d-car[a].d; if(status.d<0) status.d+=l;//如果距离是负数说明是绕了一圈 status.v=0; if(car[a].v>=0&&car[b].v<=0) { status.v=abs(car[a].v)+abs(car[b].v); } else if(car[a].v>=0&&car[b].v>=0) { if(car[a].v>car[b].v) { status.v=car[a].v-car[b].v; } } else if(car[a].v<=0&&car[b].v<=0) { if(abs(car[a].v)<abs(car[b].v)) { status.v=abs(car[b].v)-abs(car[a].v); } } //除了上面那几种情况之外,ab都不可能通过这段status.d圆弧相遇 return status;}int main(){ if (fopen("in.txt", "r") != NULL) { freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); } int t; cin>>t; while(t--) { memset(vis,false,sizeof vis); scanf("%d%d",&n,&l); for(int i=0; i<n; i++) { scanf("%d",&car[i].d); } for(int i=0; i<n; i++) { scanf("%d",&car[i].v); } for(int i=0; i<n; i++) { car[i].i=i; } sort(car,car+n); for(int i=0; i<n; i++) { list[i].pre=i-1; list[i].next=i+1; } list[0].pre=n-1; list[n-1].next=0; priority_queue<Status> que; for(int i=0; i<n; i++) { Status status = check(i,list[i].next); if(status.v) que.push(status); } Fenshu ans; int cnt=0; while(que.size()) { Status top = que.top(); que.pop(); if(vis[top.a]||vis[top.b])//如果有一个是不存在了的,那么就应该不进行下面的计算 { bool dela=false,delb=false; if(vis[top.a]) { dela=true; } if(vis[top.b]) { delb=true; } if(dela==false&&delb==true)//重新考虑没死的两边新的情况 { Status status = check(top.a,list[top.a].next); if(status.v) que.push(status); } if(dela==true&&delb==false) { Status status = check(list[top.b].pre,top.b); if(status.v) que.push(status); } continue; } ans={top.d,top.v}; int live,dead; if(car[top.a].i>car[top.b].i) { dead=top.b; live=top.a; } else { dead=top.a; live=top.b; } vis[dead]=true; del(dead); Status status; if(live==top.a) status=check(live,list[live].next); else status=check(list[live].pre,live); if(status.v) que.push(status); } ans.reduce(); printf("%lld/%lld\n",ans.fenzi,ans.fenmu); } return 0;}