• 1112 KGold


    给出N个人在0时刻的财富值M[i](所有人在0时刻的财富互不相等),以及财富增长速度S[i],随着时间的推移,某些人的财富值会超越另外一些人。如果时间足够长,对于财富增长最快的人来说,他的财富将超越所有其他对手。

    求发生的前10000次超越,分别是谁超过了谁?如果总的超越次数不足10000,则输出所有超越,如果1次超越都不会发生,则输出No Solution。
    输出按照超越发生的时间排序,同一时刻发生的超越,按照超越者的编号排序,如果编号也相同,则按照被超越者的编号排序。所有排序均为递增序。
    Input
    第1行:N,表示人的数量。(1 <= N <= 10000)
    第2 - N + 1行:每行2个数,分别是初始的财富值M[i],和财富增长速度S[i]。(0 <= M[i] <= 10^5, 1 <= S[i] <= 100)
    Output
    输出前10000次超越,超越者和被超越者的编号。如果总的超越次数不足10000,则输出所有。如果1次超越都不会发生,则输出No Solution。
    输出按照超越发生的时间排序,同一时刻发生的超越,按照超越者的编号排序,如果超越者编号也相同,则按照被超越者的编号排序。所有排序均为递增序。
    Input示例
    4
    1 100
    2 100
    3 1
    4 50
    
    Output示例
    2 3
    1 3
    2 4
    1 4
    以时间为x轴,财富为y轴建立坐标系,则超越就是两条直线的交点且有交点必须满足s[i]>s[j],w[i]<w[j].n条直线最多有n*(n-1)/2条交点,全部储存消耗内存,可以二分时间确定某时刻交点的个数
    #include <bits/stdc++.h>
    using namespace std;
    #define esp 1e-9
    typedef long long ll;
    int n;
    struct point{
        double w,s;
        int id;
        bool operator<(const point &a) const {
            return a.w>w;
        }
    }e[10005];
    struct Cost{
        double cost;
        int id;
        bool operator<(const Cost &a) const {
            return a.cost>cost;
        }
    }f[10006];
    struct node
    {
        double time;
        int idx,idy;
        bool operator<(const node &a)const {
            return fabs(a.time-time)<esp?(a.idx==idx?a.idy<idy:a.idx<idx):a.time<time;
        }
    }p;
    priority_queue<node>q;
    int solve(double mid)
    {
        for(int i=1;i<=n;i++){
            f[i].id=i;
            f[i].cost=mid*e[i].s+e[i].w;
        }
        sort(f+1,f+n+1);
        int ans=0;
        for(int i=1;i<=n;i++)
            if(i<f[i].id) ans+=f[i].id-i;
        return ans>10000;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%lf%lf",&e[i].w,&e[i].s);
            e[i].id=i;
        }
        sort(e+1,e+n+1);
        double l=1.0,r=100000005.0;
        while(r-l>0.00001){
            double mid=(l+r)/2;
            if(solve(mid)) r=mid;
            else l=mid;
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<i;j++)
            {
                if(e[j].s>e[i].s)
                {
                    p.time=(e[i].w-e[j].w)*1.0/(e[j].s-e[i].s);
                    if(p.time>esp && p.time<r)
                    {
                        p.idx=e[j].id;
                        p.idy=e[i].id;
                        q.push(p);
                    }
                }
            }
        for(int i=0;i<10000;i++)
        {
            if(!q.empty()){
                printf("%d %d
    ",q.top().idx,q.top().idy);
                q.pop();
            }
            else break;
        }
        return 0;
    }
  • 相关阅读:
    HDUOJ-----Difference Between Primes
    HDUOJ----(4706)Children's Day
    poj-------Common Subsequence(poj 1458)
    poj----Maximum sum(poj 2479)
    scanf/sscanf %[]格式控制串的用法(转)
    HDUOJ--------Text Reverse
    HDUOJ---hello Kiki
    HDUOJ-----X问题
    POJ-----C Looooops
    POJ--Strange Way to Express Integers
  • 原文地址:https://www.cnblogs.com/shinianhuanniyijuhaojiubujian/p/9572840.html
Copyright © 2020-2023  润新知