zoukankan      html  css  js  c++  java
  • CF536C-Tavas and Pashmaks【凸壳】

    正题

    题目链接:https://codeforces.com/contest/536/problem/C


    题目大意

    (n)个人,第(i)个人的游泳速度(s_i),跑步速度是(r_i)。如果跑道长度是(R),泳道长度是(S)那么一个人的用时就是(frac{R}{r_i}+frac{S}{s_i}),在(R/S)不定的情况下然后求出所有可能是用时最短的人。

    (1leq nleq 10^5,1leq s_i,r_ileq 10^4)


    解题思路

    (k=frac{R}{S}),那么用时可以化为(frac{k}{r_i}+frac{1}{s_i})

    然后对于一个点((-frac{1}{r_i},frac{1}{s_i})),我们可以视为用一条斜率为(k)的斜线去截这些点然后让截距最小。

    直接维护一个凸壳就好了,然后注意因为(R/S)都是正数所以(k)也得是正数,所以要把后段丢掉。

    时间复杂度:(O(nlog n))

    当然还有一个更神奇的做法,因为对于一个(s_i)我们只需要最大的(r_i)所以有用的点数不超过(10^4),可以直接平方暴算。


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=2e5+10;
    const double eps=1e-8;
    struct node{
    	double x,y;int id;
    }q[N];
    int n,top,s[N],ans[N],l[N];
    bool cmp(node x,node y)
    {return (x.x==y.x)?(x.y>y.y):(x.x<y.x);}
    double slope(node a,node b)
    {return (b.y-a.y)/(b.x-a.x);}
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		double x,y;q[i].id=i;
    		scanf("%lf%lf",&x,&y);
    		q[i].x=1e5/x;q[i].y=1e5/y;
    	}
    	sort(q+1,q+1+n,cmp);
    	for(int i=1;i<=n;i++)
    		if(q[i].x==q[i-1].x&&q[i].y==q[i-1].y)l[i]=l[i-1];
    		else l[i]=i;
    	for(int i=1;i<=n;i++){
    		if(q[i].x==q[i+1].x)continue;
    		while(top>1&&slope(q[s[top-1]],q[s[top]])-eps>slope(q[s[top-1]],q[i]))top--;
    		s[++top]=i;
    	}
    	for(int i=1;i<=top;i++){
    		for(int j=l[s[i]];j<=s[i];j++)
    		ans[q[j].id]=1;
    		if(q[s[i]].y<=q[s[i+1]].y)break;
    	}
    	for(int i=1;i<=n;i++)
    		if(ans[i])printf("%d ",i);
    	return 0;
    }
    
  • 相关阅读:
    Kubernetes日志的6个最佳实践
    如何选出适合自己的管理Helm Chart的最佳方式?
    授权权限服务设计解析
    微服务中如何设计一个权限授权服务
    微服务中的网关
    ketchup服务治理
    ketchup 消息队列rabbitmq使用
    ketchup 注册中心consul使用
    微服务框架 ketchup 介绍
    微服务框架surging学习之路——序列化
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/15377179.html
Copyright © 2011-2022 走看看