zoukankan      html  css  js  c++  java
  • P3222 [HNOI2012]射箭

    题意

    考虑二分答案,我们只需要判断是否存在((a,b)),对于任意(iin[1,mid])满足(ax_i^2+bx_iin[y_{1i},y_{2i}])

    展开可得:
    (frac{y_{1i}}{x_i}leqslant ax_i+bleqslantfrac{y_{2i}}{x_i})
    即:
    (ax_i+b-frac{y_{1i}}{x_i}geqslant 0)
    (ax_i+b-frac{y_{12}}{x_i}leqslant 0)

    (a,b)当成(x,y),这是两条直线,我们半平面交判断即可。

    然后这题卡精度卡了我一下午,我也是真有耐心。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    #define double long double
    const int maxn=100010;
    const double eps=1e-18;
    const double inf=1e12;
    int n,m;
    struct Point
    {
        double x,y;
        inline double len(){return sqrt(x*x+y*y);}
        Point operator+(const Point a)const{return (Point){x+a.x,y+a.y};}
        Point operator-(const Point a)const{return (Point){x-a.x,y-a.y};}
        Point operator*(const double k){return (Point){x*k,y*k};}
        Point operator/(const double k){return (Point){x/k,y/k};}
        double operator*(const Point a)const{return x*a.y-y*a.x;}
        double operator&(const Point a)const{return x*a.x+y*a.y;}
    };
    inline int dcmp(double x)
    {
        if(fabs(x)<=eps)return 0;
        return x<0?-1:1;
    } 
    inline Point get(Point a,Point b){return b-a;}
    struct Line
    {
        Point p,v;int id;double theta;
        bool operator<(const Line a)const
        {
            return !dcmp(theta-a.theta)?dcmp(get(p,v)*get(p,a.v))<0:dcmp(theta-a.theta)<0;
        } 
    }line[maxn<<1],tmp[maxn<<1],q[maxn<<1];
    inline Point getpoint(Line a,Line b)
    {
        Point p1=a.p,p2=b.p,v1=a.v,v2=b.v;
        v1=get(p1,v1),v2=get(p2,v2);
        Point u=get(p1,p2);
        return p2+v2*(u*v1)/(v1*v2);
    }
    inline bool check(Line a,Line b,Line c)
    {
        Point p=getpoint(a,b);
        return dcmp(get(c.p,c.v)*get(c.p,p))<0;
    }
    inline bool check_ans(int mid)
    {
        int l=1,r=0,cnt=0;
        for(int i=1;i<=m;i++)
        	if(line[i].id<=mid&&line[i].theta!=tmp[cnt].theta)tmp[++cnt]=line[i];
        for(int i=1;i<=cnt;i++)
        {
            while(l<r&&check(q[r-1],q[r],tmp[i]))r--;
            while(l<r&&check(q[l],q[l+1],tmp[i]))l++;
            q[++r]=tmp[i];
        }
        while(l<r&&check(q[r-1],q[r],q[l]))r--;
        while(l<r&&check(q[l],q[l+1],q[r]))l++;
        return r-l+1>=3;
    }
    int main()
    {
    	//freopen("test.in","r",stdin);
    	//freopen("test.out","w",stdout);
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		double x,y1,y2;scanf("%Lf%Lf%Lf",&x,&y1,&y2);
    		line[++m]=(Line){(Point){0,y1/x},(Point){1,y1/x-x},i,0};
    		line[++m]=(Line){(Point){1,y2/x-x},(Point){0,y2/x},i,0};
    	}
    	line[++m]=(Line){(Point){-inf,eps},(Point){-eps,eps},0,0};
    	line[++m]=(Line){(Point){-eps,eps},(Point){-eps,inf},0,0};
    	line[++m]=(Line){(Point){-eps,inf},(Point){-inf,inf},0,0};
    	line[++m]=(Line){(Point){-inf,inf},(Point){-inf,eps},0,0};
    	for(int i=1;i<=m;i++)line[i].theta=atan2(line[i].v.y-line[i].p.y,line[i].v.x-line[i].p.x);
        sort(line+1,line+m+1);
    	int l=1,r=n,res=0;
    	while(l<=r)
    	{
    		int mid=(l+r)>>1;
    		if(check_ans(mid))res=mid,l=mid+1;
    		else r=mid-1;
    	}
    	printf("%d
    ",res);
    	return 0;
    }
    
  • 相关阅读:
    lamp环境安装二
    ubuntu14.04 sublime 出错
    lamp环境安装一
    jsp(Java Server Pages)和js(JavaScript)的区别:
    form表单验证jquery
    数据库分离 脱机
    数据绑定ds.ReadXml(stream);
    自定义类型转化
    temp
    一般处理程序获得一个链接返回的值
  • 原文地址:https://www.cnblogs.com/nofind/p/12244720.html
Copyright © 2011-2022 走看看