• 炮艇大赛之正式赛


    题目

    Description
    炮艇大赛是一项危险的比赛。为了赢得这场比赛,参赛者可能会牺牲自己的生命。

    参赛者将会在一条长度为(L)的环形轨道上比赛。在比赛开始时((0)时刻),所有参赛者站在轨道不同的位置上,其中第 i 名参赛者站在位置 (di(0≤di<L)) 上。然后比赛开始。每位参赛者驾驶着它的炮艇,速度为 (vi) (速度可以为正,可以为负,也可以为(0)。速度为正表示参赛者顺时针移动,速度为负表示参赛者逆时针移动)。每位参赛者的速度都不同。

    (i) 名参赛者有 (i) 点能量值。在比赛过程中,参赛者们可能会相遇(此处相遇指的是参赛者们在同一时刻恰好落在同一地点)。每两位参赛者 (i,j) 相遇时,能量值低的参赛者将被击毙出局。

    当赛场上只剩下一个人时,比赛结束。

    问比赛什么时候结束。

    Input
    第一行包含两个正整数 (n,L(1leq n leq 10^5,1leq Lleq 10^9))

    接下来一行包含 n 个不同的整数 (di(0leq di < L))

    接下来一行包含 n 个不同的整数 $vi(|vi| leq109) $

    Output
    输出一个分数 (X/Y) 表示结束时刻,其中 (gcd(X,Y)=1) 。若答案为(0),应只输出“(0)”(不含引号)。

    题解

    直接模拟。
    先排序。
    显然最先相遇的一定相邻的。
    于是我们把相邻的炮艇的相遇时间扔进小根堆。然后取出堆顶, 将被打败的删掉, 然后将新产生的相邻的炮艇的相遇时间扔进小根堆(这里可以用链表模拟炮艇序列)。 重复这个过程, 直到只剩一艘快艇。

    代码

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    #include <vector>
    #include <queue>
    
    using namespace std;
    
    
    typedef long long LL;
    
    
    typedef pair <LL, LL> pr;
    
    
    inline LL gcd(LL a, LL b) { return !b ? a : gcd(b, a % b); }
    
    
    const int N = 1e5 + 10;
    
    
    struct Data
    {
    	int x, y; double t;
    	Data() { }
    	Data(int _1, int _2, double _3) : x(_1), y(_2), t(_3) { }
    	inline bool operator < (Data rhs) const { return t > rhs.t; }
    };
    
    
    priority_queue <Data> q;
    
    
    int n; LL L;
    
    
    struct Info
    {
    	LL d, v; int w, pre, nxt; 
    	Info() { }
    	Info(LL _1, LL _2, int _3, int _4, int _5) : d(_1), v(_2), w(_3), pre(_4), nxt(_5) { }
    } a[N];
    
    
    pr calc(int x, int y)
    {
    	if (a[x].v >= a[y].v) return make_pair((a[y].d - a[x].d + L) % L, a[x].v - a[y].v);
    	return make_pair(L - ((a[y].d - a[x].d + L) % L), a[y].v - a[x].v);
    }
    
    
    bool tag[N];
    
    
    int main()
    {
    	scanf("%d %lld", &n, &L);
    	
    	if (n <= 1) return 0 & puts("0");
    	
    	for (int i = 1; i <= n; i++)
    		scanf("%lld", &a[i].d);
    	for (int i = 1; i <= n; i++)
    		scanf("%lld", &a[i].v), a[i].w = i;
    	
    	sort(a + 1, a + 1 + n, [](Info a, Info b) { return a.d < b.d; });
    	
    	a[1].pre = n; a[1].nxt = 2;
    	a[n].pre = n - 1; a[n].nxt = 1;
    	for (int i = 2; i < n; i++)
    		a[i].pre = i - 1, a[i].nxt = i + 1;
    	
    	for (int i = 1; i <= n; i++)
    	{
    		pr t = calc(i, a[i].nxt);
    		q.push( Data(i, a[i].nxt, (double) t.first / t.second) );
    	}
    	
    	int cnt = 0;
    	
    	Data tmp;
    	while (q.size() > 1) 
    	{
    		tmp = q.top(); q.pop();
    		if (tag[tmp.x] || tag[tmp.y]) continue;
    		cnt++;
    		if (cnt == n-1) break;
    		if (a[tmp.x].w > a[tmp.y].w)
    		{
    			tag[tmp.y] = 1;
    			a[tmp.x].nxt = a[tmp.y].nxt;
    			a[a[tmp.x].nxt].pre = tmp.x;
    			pr t = calc(tmp.x, a[tmp.x].nxt);
    			q.push( Data(tmp.x, a[tmp.x].nxt, (double) t.first / t.second) );
    		}
    		else
    		{
    			tag[tmp.x] = 1;
    			a[tmp.y].pre = a[tmp.x].pre;
    			a[a[tmp.y].pre].nxt = tmp.y;
    			pr t = calc(a[tmp.y].pre, tmp.y);
    			q.push( Data(a[tmp.y].pre, tmp.y, (double) t.first / t.second) );
    		}
    	}
    	
    	tmp = q.top();
    	pr t = calc(tmp.x, tmp.y);
    	printf("%lld/%lld
    ", t.first / gcd(t.first, t.second), t.second / gcd(t.first, t.second));
    	
    	return 0;
    }
    
  • 相关阅读:
    当数据库遇上外键
    java EE实现动态SQL的
    Java EE注册三部曲(一步曲)
    xml+js+html的二级联动
    MySQL中like的使用方法
    oracle 外部表查alter日志
    oracle 预安装命令
    LINUX 安装增强 前置安装文件
    linux 6.5 网卡
    liunux 6.5设置网卡默认开启
  • 原文地址:https://www.cnblogs.com/2016gdgzoi509/p/11305273.html
Copyright © 2020-2023  润新知