zoukankan      html  css  js  c++  java
  • P3291 [SCOI2016]妖怪

    P3291 [SCOI2016]妖怪

    链接

    P3291 [SCOI2016]妖怪

    题解

    本来是想写凸包的,但是人太懒了。。。。
    把每个妖怪视为平面上点,那么就是要找到一个斜率,使这个斜率经过每个点得到的最大截距和最小。
    显然答案是在凸包上的,对于每个斜率,都可以在凸包上找到最优的点。
    每个凸包上的点都在某个区间的斜率的时候是最大值,找到每个点最大时的区间在讨论即可。。。效率是(O(nlogn))
    然而我没写凸包。。。
    因为这个显然可以二分答案的。。二分答案后我们要求每个点符合条件时的斜率区间,然后合并一下就行。
    效率是(O(nlogV)) 的。

    (Code)

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int N=1e6+10;
    const double eps=1e-6;
    const double INF=1e16;
    const double X4=4;
    const double X2=2;
    const double X0=0;
    int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    void print(LL x){
        if(x>9) print(x/10);
        putchar(x%10+'0');
    }
    
    int n; 
    
    struct node{
    	double x,y;
    }a[N];
    
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i){
    		a[i].x=read();
    		a[i].y=read();
    	}
    	double l=0,r=1e9,mid,A,B,C,mn,mx,del;
    	bool flag=0;
    	while(r-l>eps){ 
    		mid=(l+r)/2;
    		flag=0;
    		mn=-INF;mx=INF;
    		for(int i=1;i<=n;++i){
    			A=a[i].x;
    			B=-(mid-a[i].x-a[i].y);
    			C=a[i].y;
    			del=B*B-X4*A*C;
    			if(del<0) {
    				flag=1;break;
    			}
    			mx=min(mx,(-B+sqrt(del))/X2/A);
    			mn=max(mn,(-B-sqrt(del))/X2/A);
    		}
    		if(mn<=mx&&mx>X0&&flag==0) r=mid;
    		else l=mid;
    	}
    	printf("%0.4lf
    ",l);
    	return 0;
    }
    
  • 相关阅读:
    java中继承和多态的理解
    汽车租赁系统
    s2第六章继承和多态
    第三章泛型集合ArrayList 和Hashtable
    第二章项目总结
    s2第二章深入c#类型
    .NET平台
    航班查询系统
    java初始重点语法
    JDBC
  • 原文地址:https://www.cnblogs.com/Yuigahama/p/13793619.html
Copyright © 2011-2022 走看看