hdu 6136 Death Podracing(模拟)

题目链接:hdu 6136 Death Podracing

题意:

有n个人在一个环形的跑道上,第i个人有一个power i,每个人有一个起始点和一个不同的速度。

如果两个人相遇,那么power大的那个人就会将power小的那个人淘汰出局。

然后问决出胜负需要多少时间。

题解:

显然,每次有人被淘汰出局的时候,都是被相邻的人干掉的,那么我们先预处理出相邻的人相遇的时间,然后扔进优先队列里面,每次选择最小的时间,将一个人淘汰掉,然后再更新一下当前的局势就行了。

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 3 using namespace std;
 4 typedef pair<int,int>P;
 5
 6 const int N=1e5+7;
 7 int t,n,L,head,vis[N],rev[N],TIM;
 8
 9 struct VAL
10 {
11     int a,b,x,y;double val;
12     VAL(){}
13     VAL(int _a,int _b,int _x,int _y):a(_a),b(_b),x(_x),y(_y){val=1.0*_a/_b;}
14     bool operator <(const VAL&B)const{return val>B.val;}
15 };
16 struct LIST{int idx,pre,nxt;}lst[N];
17 P a[N],tmp[N];
18 priority_queue<VAL>Q;
19
20 VAL cal(int x,int y)
21 {
22     if(a[x].first>a[y].first)swap(x,y);
23     int dis,V=abs(a[x].second-a[y].second);
24     if(a[x].second>a[y].second)
25         dis=a[y].first-a[x].first;
26     else dis=L-a[y].first+a[x].first;
27     int gcd=__gcd(dis,V);
28     dis/=gcd,V/=gcd;
29     return VAL(dis,V,x,y);
30 }
31
32 void del(int x,int y)
33 {
34     int lx=rev[x],ly=rev[y];
35     if(lst[lx].pre==ly)
36     {
37         lst[lx].pre=lst[ly].pre;
38         lst[lst[ly].pre].nxt=lx;
39         Q.push(cal(x,lst[lst[ly].pre].idx));
40     }else
41     {
42         lst[lx].nxt=lst[ly].nxt;
43         lst[lst[ly].nxt].pre=lx;
44         Q.push(cal(x,lst[lst[ly].nxt].idx));
45     }
46 }
47
48 int main(){
49     scanf("%d",&t);
50     while(t--)
51     {
52         TIM++,scanf("%d%d",&n,&L);
53         F(i,1,n)scanf("%d",&a[i].first);
54         F(i,1,n)scanf("%d",&a[i].second);
55         F(i,1,n)tmp[i]=P(a[i].first,i);
56         sort(tmp+1,tmp+1+n),head=1;
57         F(i,1,n)lst[i]=LIST{tmp[i].second,i-1,i+1},rev[tmp[i].second]=i;
58         lst[n].nxt=1,lst[1].pre=n;
59         while(!Q.empty())Q.pop();
60         F(i,1,n)Q.push(cal(lst[i].idx,lst[lst[i].nxt].idx));
61         VAL ans;
62         F(i,2,n)
63         {
64             VAL now=Q.top();Q.pop();
65             while(vis[now.x]==TIM||vis[now.y]==TIM)
66                 now=Q.top(),Q.pop();
67             if(i==n)ans=now;
68             int x=now.x,y=now.y;
69             if(x<y)swap(x,y);
70             del(x,y),vis[y]=TIM;
71         }
72         printf("%d/%d\n",ans.a,ans.b);
73     }
74     return 0;
75 }

时间: 2024-12-30 04:25:28

hdu 6136 Death Podracing(模拟)的相关文章

HDU 6136 Death Podracing(循环链表)

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6136 [题目大意] 一堆人在操场上跑步,他们都有一定的速度和初始位置, 当两个人相遇的时候编号较小的就会出局,当场上剩下最后一个人的时候游戏结束, 问时长为多少 [题解] 我们发现每次发生碰撞的一定是相邻的两个人, 所以我们找出相邻关系中最先发生碰撞的,将碰撞失败的那个人删除, 之后继续这个过程, 按照上述的做法我们建立一个循环链表,把所有人串起来, 当发生淘汰的时候把那个人从循环链表中删去即可

HDU 6136 Death Podracing (堆)

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6136 题解 完了,普及题都不会做了... 发现一个重要性质是只有相邻的人才会相撞,于是直接拿堆维护即可... WA了好几发... 代码 #include<cstdio> #include<cstdlib> #include<cstring> #include<queue> #include<algorithm> #define llong long

HDU 6136 Death Podracing

题意 给定长l的环上的n个人,每个人有给不相同的速度和位置,相遇时编号大的存活,问最后留存一个人时的时间 做法 直接用堆来模拟即可 #include <bits/stdc++.h> using namespace std; typedef long long LL; struct Frac { LL fz, fm; Frac() {} template<class T> Frac(T a):fz(a), fm(1) {} template<class T> Frac(T

hdu 1175 连连看(模拟循环队列)

连连看 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 18149    Accepted Submission(s): 4741 Problem Description "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条

HDU 4608 I-number--简单模拟

I-number Time Limit: 5000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 The I-number of x is defined to be an integer y, which satisfied the the conditions below: 1.  y>x; 2.  the sum of each digit of y(under base 10) is the multiple of 10; 3.  among all

hdu 4831 Scenic Popularity(模拟)

题目链接:hdu 4831 Scenic Popularity 题目大意:略. 解题思路:对于休闲区g[i][0]和g[i][1]记录的是最近的两个景点的id(只有一个最近的话g[i][1]为0),对于景点来说,g[i][0]为-1(表示该id对应的是景点),g[i][1]为该景点的热度值.主要就是模拟,注意一些细节就可以了. #include <cstdio> #include <cstring> #include <cstdlib> #include <alg

hdu 3125 Slash(模拟)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3125 Problem Description The American English slash (/) is a punctuation mark. In the early modern period, in the Fraktur script, which was widespread through Europe in the Middle Ages, one slash(/) repr

hdu 4858 项目管理(vector模拟)

# include <stdio.h> # include <algorithm> # include <string.h> # include <vector> # define N 100005 using namespace std; vector<int>g[N]; int node[N]; int slove(int x) { int sum=0,i; for(i=0;i<g[x].size();i++) { sum+=node[

hdu 4941 STL HASH 模拟

http://acm.hdu.edu.cn/showproblem.php?pid=4941 比赛的时候现学的map的find...以前都是用下标做的,但是map用下标查询的话,如果查询的元素不存在,会插入一个新的元素. 贴一个map查找元素找到和找不到的模板 map<pair<int,int>,int>::iterator it=poshash.find(tmppos);//pair<int,int>poshash; int pp; if(it == poshash.