HDU 6136 Death Podracing 优先队列+模拟

题目:http://acm.hdu.edu.cn/showproblem.php?pid=6136

题意:在一个环上有n个人,每个人在不同的初始位置以及有不同的速度,每个人的武器强度为i,当相遇时武器强度弱的死亡,问比赛结束时的时间

 

看了题解还是写了很久 开始自己维护的太复杂 实际上只需要维护左右是谁就行了

官方题解 :

解法一
第一种解法比较直观,最初始状态环上有 nnn 个人,第一次淘汰发生必然是环上相邻的两个人相撞。注意到第一个被淘汰的人不会对后续过程有任何影响,如果我们能找出谁是第一个被淘汰的,直接把这个人从初始状态中删除,就能把问题变成一个只有 n−1n-1n1 个人的子问题,这个子问题和原问题有相同的答案。
于是我们可以用一个堆维护环上所有相邻人相遇的时间,从中取出最小值,就能找到第一个被淘汰的人,这个人删除后,原本不相邻的两个人就相邻了,同样求出他们的相遇时间,加入堆中,重复执行这一过程,直到找到最后一个被淘汰的人为止。算法复杂度 O(nlogn)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define lson i<<1
#define rson i<<1|1
using namespace std;
const int N=2e5+5;
int d[N],v[N],l[N],r[N];
bool use[N];
int n,len;
struct people
{
    int d,v,num;
    bool operator <(const people&tem) const
    {
        return d<tem.d;
    }
}a[N];
struct p
{
    int x,y;
    double t;
    p(int xx=0,int yy=0)
    {
        x=xx;y=yy;
        if (x>y)
        {
            if (a[x].v>a[y].v)
                t=(len-abs(a[y].d-a[x].d))*1.0/(abs(a[y].v-a[x].v)*1.0);
            else t=abs(a[y].d-a[x].d)*1.0/(abs(a[y].v-a[x].v)*1.0);
        }
        else
        {
            if (a[y].v>a[x].v)
                t=(len-abs(a[y].d-a[x].d))*1.0/(abs(a[y].v-a[x].v)*1.0);
            else t=abs(a[y].d-a[x].d)*1.0/(abs(a[y].v-a[x].v)*1.0);
        }
    }
    bool operator <(const p&tem) const
    {
        return t>tem.t;
    }
};
int gcd(int x,int y)
{
    if (x<y) swap(x,y);
    int t;
    while(y)
    {
        t=x%y;
        x=y;
        y=t;
    }
    return x;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&len);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i].d);
            a[i].num=i;
        }
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i].v);
        sort(a+1,a+1+n);
        priority_queue<p> que;
        for(int i=1;i<=n;i++)
        {
            que.push(p(i,i+1>n?1:i+1));
            l[i]=i-1<1?n:i-1;
            r[i]=i+1>n?1:i+1;
        }
        memset(use,0,sizeof(use));
        int sz=n-1;
        int x,y;
        while(!que.empty())
        {
            p t=que.top();que.pop();
            if (use[t.x]||use[t.y]) continue;
            if (a[t.x].num<a[t.y].num)
            {
                use[t.x]=1;
                l[t.y]=l[t.x];r[l[t.x]]=t.y;
                que.push(p(l[t.x],t.y));
            }
            else
            {
                use[t.y]=1;
                r[t.x]=r[t.y];l[r[t.y]]=t.x;
                que.push(p(t.x,r[t.y]));
            }
            sz--;
            if (sz==0)
            {
                x=t.x;y=t.y;
                break;
            }
        }
        int t1=abs(a[x].d-a[y].d);
        int t2=abs(a[x].v-a[y].v);
        if ((x>y&&a[x].v>a[y].v)||(x<y&&a[y].v>a[x].v))
            t1=len-t1;
        int tt=gcd(t1,t2);
        t1/=tt;t2/=tt;
        printf("%d/%d\n",t1,t2);
    }
    return 0;
}

  

posted @ 2017-08-18 10:53  BK_201  阅读(248)  评论(0编辑  收藏  举报