• 【题解】【HDU6136】2017多校第8场 炮艇大赛之正式赛


    用了个比较显然的做法

    思路:

    第一次相遇的必是两个环上相邻的两个人

    正确性显然

    第一个出局的人不会对后续的状态有任何影响

    同上,显然

    于是我们就把问题的规模从n缩小到了n-1

    对于缩小后的子问题,我们也能用同样的方法

    但同时,原本不相邻的现在相邻了

    于是我们需要一种方法,来快速取得最小值,并支持插入

    很显然,这就是堆

    搞定了……

    时间复杂度(O(nlogn))

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    
    const int N=100010;
    
    struct note {
        int x,y;
        note(int u=0,int v=1){
            x=u;
            y=v;
        }
    };
    
    bool operator < (const note &x,const note &y) {
        return x.x/(double)x.y>y.x/(double)y.y;
    }
    
    note operator + (const note &x,const note &y) {
        return note(x.x*y.y+y.x*x.y,x.y*y.y);
    }
    
    note operator - (const note &x,const note &y) {
        return note(x.x*y.y-y.x*x.y,x.y*y.y);
    }
    
    struct data {
        int x,y;
        note t;
    };
    
    bool operator < (const data &a,const data &b) {
        return a.t<b.t;
    }
    
    struct boat {
        int d;
        int v;
        int val;
    };
    
    bool operator < (const boat &x,const boat &y) {
        return x.d<y.d;
    }
    
    int n,L;
    note ans;
    data e;
    boat a[N];
    priority_queue<data> q;
    bool out[N];
    
    note get(boat x,boat y) {
        if (x.d<y.d) {
            if (x.v<y.v) {
                return note(L-y.d+x.d,y.v-x.v);
            } else {
                return note(y.d-x.d,x.v-y.v);
            }
        } else {
            if (x.v<y.v) {
                return note(x.d-y.d,y.v-x.v);
            } else {
                return note(L-x.d+y.d,x.v-y.v);
            }
        }
    }
    
    inline int gcd(int x,int y) {
        while(y^=x^=y^=x%=y);
        return x;
    }
    
    inline bool comp(const boat &x,const boat &y) {
        return x.d<y.d;
    }
    
    int main() {
        scanf("%d %d",&n,&L);
        for(int i=1;i<=n;i++) {
            scanf("%d",&a[i].d);
            a[i].val=i;
        }
        for(int i=1;i<=n;i++) {
            scanf("%d",&a[i].v);
        }
        sort(a+1,a+n+1,comp);
        e.x=n;
        e.y=1;
        e.t=get(a[1],a[n]);
        q.push(e);
        for(int i=1;i<n;i++) {
            e.x=i;
            e.y=i+1;
            e.t=get(a[i],a[i+1]);
            q.push(e);
        }
        int num=n;
        while(q.size()>1) {
            e=q.top();
            q.pop();
            if (out[a[e.x].val]||out[a[e.y].val]) {
                continue;
            }
            if (num==2) {
                break;
            }
            if (a[e.x].val<a[e.y].val) {
                out[a[e.x].val]=1;
                while(out[a[e.x].val]) {
                    e.x--;
                    if (e.x==0) {
                        e.x=n;
                    }
                }
            } else {
                out[a[e.y].val]=1;
                while(out[a[e.y].val]) {
                    e.y++;
                    if (e.y>n) {
                        e.y=1;
                    }
                }
            }
            num--;
            e.t=get(a[e.x],a[e.y]);
            q.push(e);
        }
        data k=q.top();
        ans=k.t;
        int o=gcd(ans.x,ans.y);
        printf("%d/%d",ans.x/o,ans.y/o);
        return 0;
    }
    
    
  • 相关阅读:
    坐看夕阳
    张学孟 (帮别人名字作诗)
    光棍节有感
    我懂
    陶婷(帮别人名字作诗)
    你的爱是不是在等着我
    OpenCV数据读写操作
    数字图像处理中的形态学
    C++/C学习笔记(一)
    利用opencv绘制 灰度直方图 RGB直方图 HSV直方图 直方图均衡化
  • 原文地址:https://www.cnblogs.com/tt66ea-blog/p/11305583.html
Copyright © 2020-2023  润新知