HDU 6136 Death Podracing 优先队列 + 循环链表(模拟)

来源:互联网 发布:网络之纵横天下同人 编辑:程序博客网 时间:2024/05/18 16:37

传送门:HDU6136

题意:n个人在圆形上运动,他们都有一定的速度和初始位置,当两个人相遇的时候编号较小的就会出局,当场上剩下最后一个人的时候游戏结束,问多长时间游戏会结束。

思路:官方题解:



我用的是解法一。

代码:

#include<bits/stdc++.h>#define ll long long#define inf 0x3f3f3f3fusing namespace std;typedef pair<int,int> P;const int MAXN = 100010;struct node{int d, w, v;bool operator < (node a) const{return d < a.d;} }p[MAXN];int pre[MAXN], nxt[MAXN], book[MAXN];struct ac{int id1, id2;double t;ac(int _id1 = 0, int _id2 = 0, double _t = 0) : id1(_id1), id2(_id2), t(_t) {}bool operator < (ac a) const{return t > a.t;}};int L;double calc(int a, int b){int v = p[a].v - p[b].v;int d = p[b].d - p[a].d;if(d < 0) d += L;if(v < 0) d = L - d, v = -v;if(v == 0) return inf;return d * 1.0 / v;}priority_queue<ac> q;void del(int id){book[id] = 1;q.push(ac(pre[id], nxt[id], calc(pre[id], nxt[id])));nxt[pre[id]] = nxt[id];pre[nxt[id]] = pre[id];}int main(){int T;cin >> T;while(T--){int n;memset(book, 0, sizeof book);scanf("%d %d", &n, &L);for(int i = 0; i < n; i++)scanf("%d", &p[i].d), p[i].w = i;for(int i = 0; i < n; i++)scanf("%d", &p[i].v);sort(p, p + n);for(int i = 0; i < n; i++){nxt[i] = (i + 1) % n;pre[i] = (i - 1 + n) % n;q.push(ac(i, nxt[i], calc(i, nxt[i])));}ac tmp;while(!q.empty()){tmp = q.top(); q.pop();if(book[tmp.id1] || book[tmp.id2]) continue;if(n == 2) break;n--;if(p[tmp.id1].w > p[tmp.id2].w) del(tmp.id2);else del(tmp.id1);}while(!q.empty()) q.pop();if(tmp.id2 < tmp.id1) swap(tmp.id1, tmp.id2);int fm = p[tmp.id1].v - p[tmp.id2].v;int fz = p[tmp.id2].d - p[tmp.id1].d;if(fz < 0) fz += L;if(fm < 0) fz = L - fz, fm = -fm;printf("%d/%d\n", fz / __gcd(fz, fm), fm / __gcd(fz, fm));} return 0;}

第二种线性解法的思路和栈的运用都很巧妙。


原创粉丝点击