• 题解 UVA1298 【Triathlon】


    题目链接:Link

    Solution

    这题的主要思想就是数形结合。设比赛总长度为1,其中游泳长度为x,自行车长度为y,赛跑长度为 1-x-y,则选手i打败选手j(非并列)的条件是 (dfrac{x}{v_i}+dfrac{y}{u_i}+dfrac{1-x-y}{w_i}<dfrac{x}{v_j}+dfrac{y}{u_j}+dfrac{1-x-y}{w_j})

    可以把它整理成 Ax+By+C>0的形式,其中

    A=$ (dfrac{1}{v_j}-dfrac{1}{w_j})-(dfrac{1}{v_i}-dfrac{1}{w_i}) $

    B=$ (dfrac{1}{u_j}-dfrac{1}{w_j})-(dfrac{1}{u_i}-dfrac{1}{w_i}) $

    C=$ dfrac{1}{w_j}-dfrac{1}{w_i} $

    则得到的所有半平面的并就是合法的解,可以由此判断是否能夺冠。

    贴代码:

    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<vector>
    #include<algorithm>
    using namespace std;
    struct Point
    {
    	double x,y;
    	Point(double x=0,double y=0):x(x),y(y){}
    };
    typedef Point Vector;
    
    inline Vector operator+(const Vector &A,const Vector &B)
    { return Vector(A.x+B.x,A.y+B.y); }
    
    inline Vector operator-(const Point &a,const Point &b)
    { return Vector(a.x-b.x,a.y-b.y); }
    
    inline Vector operator*(const Vector &A,double p)
    { return Vector(A.x*p,A.y*p); }
    
    inline Vector operator/(const Vector &A,double p)
    { return Vector(A.x/p,A.y/p); }
    
    inline bool operator<(const Point &a,const Point &b)
    { return a.x<b.x||(a.x==b.x&&a.y<b.y); }
    
    const double ops=1e-10;
    inline int dcmp(double x)
    { return (x>0?x:-x)<ops?0:(x>0?1:-1); }
    
    inline bool operator==(const Point &a,const Point &b)
    { return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; }
    
    inline double Dot(const Vector &A,const Vector &B)
    { return A.x*B.x+A.y*B.y; }
    
    inline double Length(const Vector &A)
    { return sqrt(Dot(A,A)); }
    
    inline double Cross(const Vector &A,const Vector &B)
    { return A.x*B.y-A.y*B.x; }
    
    inline Vector Normal(const Vector &A)
    {
    	double L=Length(A);
    	return Vector(-A.y/L,A.x/L);
    }
    
    struct Line
    {
    	Point P;
    	Vector v;
    	double ang;
    	Line(Point P=Point(),Vector v=Vector()):P(P),v(v) { ang=atan2(v.y,v.x); }
    	inline bool operator<(const Line &L) const
    	{ return ang<L.ang; }
    };
    
    inline bool OnLeft(const Line &L,const Point &p)
    { return dcmp(Cross(L.v,p-L.P))>0; }
    
    Point GetLineIntersection(const Line &a,const Line &b)
    {
    	Vector u=a.P-b.P;
    	double t=Cross(b.v,u)/Cross(a.v,b.v);
    	return a.P+a.v*t;
    }
    
    int HalfplaneIntersection(Line *L,int n)
    {
    	sort(L,L+n);
    	int first,last;
    	Point *p=new Point[n];
    	Line *q=new Line[n];
    	q[first=last=0]=L[0];
    	for(int i=1;i<n;i++)
    	{
    		while(first<last&&!OnLeft(L[i],p[last-1])) last--;
    		while(first<last&&!OnLeft(L[i],p[first])) first++;
    		q[++last]=L[i];
    		if(dcmp(Cross(q[last].v,q[last-1].v))==0)
    		{
    			last--;
    			if(OnLeft(q[last],L[i].P)) q[last]=L[i];
    		}
    		if(first<last) p[last-1]=GetLineIntersection(q[last-1],q[last]);
    	}
    	while(first<last&&!OnLeft(q[first],p[last-1])) last--;
    	if(last-first<=1) return 0;
    	p[last]=GetLineIntersection(q[last],q[first]);
    	
    	return max(last-first+1,0);
    }
    const int maxn=110;
    const double k=10000;
    Point poly[maxn];
    Line L[maxn];
    int n;
    int V[maxn],U[maxn],W[maxn];
    int main()
    {
    #ifdef local
    	freopen("pro.in","r",stdin);
    #endif
    	while(scanf("%d",&n)==1&&n)
    	{
    		for(int i=0;i<n;i++) scanf("%d%d%d",&V[i],&U[i],&W[i]);
    		for(int i=0;i<n;i++)
    		{
    			int lc=0,ok=1;
    			for(int j=0;j<n;j++)
    				if(i!=j)
    				{
    					if(V[i]<=V[j]&&U[i]<=U[j]&&W[i]<=W[j]) { ok=0; break; }
    					if(V[i]>=V[j]&&U[i]>=U[j]&&W[i]>=W[j]) continue;
    					
    					double a=(k/V[j]-k/W[j])-(k/V[i]-k/W[i]);
    					double b=(k/U[j]-k/W[j])-(k/U[i]-k/W[i]);
    					double c=k/W[j]-k/W[i];
    					Point P;
    					Vector v(b,-a);
    					if(fabs(a)>fabs(b)) P=Point(-c/a,0);
    					else P=Point(0,-c/b);
    					L[lc++]=Line(P,v);
    				}
    			if(ok)
    			{
    				L[lc++]=Line(Point(0,0),Vector(0,-1));
    				L[lc++]=Line(Point(0,0),Vector(1,0));
    				L[lc++]=Line(Point(0,1),Vector(-1,1));
    				if(!HalfplaneIntersection(L,lc)) ok=0;
    			}
    			printf("%s
    ",ok?"Yes":"No");
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    vuejs中使用echart图表
    锚点链接
    如何动态修改网页的标题(title)?
    如何为图片添加热点链接?(map + area)
    cookie
    如何为你的网站添加标志性的图标(头像)呢?
    图片拖拽上传至服务器
    js定时器之setTimeout的使用
    input[type=file]中使用ajaxSubmit来图片上传
    input[type=file]样式更改以及图片上传预览
  • 原文地址:https://www.cnblogs.com/happyZYM/p/11380170.html
Copyright © 2020-2023  润新知