1. 程式人生 > >POJ 1755 Triathlon (計算幾何+半平面交解決線性規劃)

POJ 1755 Triathlon (計算幾何+半平面交解決線性規劃)

Triathlon is an athletic contest consisting of three consecutive sections that should be completed as fast as possible as a whole. The first section is swimming, the second section is riding bicycle and the third one is running.

The speed of each contestant in all three sections is known. The judge can choose the length of each section arbitrarily provided that no section has zero length. As a result sometimes she could choose their lengths in such a way that some particular contestant would win the competition.
Input The first line of the input file contains integer number N (1 <= N <= 100), denoting the number of contestants. Then N lines follow, each line contains three integers Vi, Ui and Wi (1 <= Vi, Ui, Wi <= 10000), separated by spaces, denoting the speed of ith contestant in each section. Output For every contestant write to the output file one line, that contains word "Yes" if the judge could choose the lengths of the sections in such a way that this particular contestant would win (i.e. she is the only one who would come first), or word "No" if this is impossible. Sample Input
9
10 2 6
10 7 3
5 6 7
3 2 7
6 2 6
3 5 7
8 4 6
10 4 2
1 8 7
Sample Output
Yes
Yes
Yes
No
No
No
Yes
No
Yes

分別對每個人列一組不等式方程組再分別對每一組不等式方程組用半平面交求解
因為沒規定跑道長度,我一開始就自己定義了一個很長的長度L,然後三個專案每一段長度為x,y,(L-x-y),
然後利用每一段的速度來求出每個人的總時間以此來列不等式方程組,但是這樣wa了N發。。。
我們可以直接定義三段的長度為x,y,1( 可以看成以一定比例縮小之後,這樣就穩了 ),然後列式子,半平面交

程式碼:
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<functional>
#include<vector>
#include <map>
#include<cmath>
using namespace std;
typedef long long LL;
const LL MOD=1e9+7;
const double eps=1e-9;
const int MAXN=100+23;
#define point pair<double,double>
#define x first
#define y second
void output(point p[],int n)
{
    puts("******points:");
    for(int i=1;i<=n;i++)
    {
        printf("%.0f %.0f\n",p[i].x,p[i].y);
    }
}
double cross(point o,point a,point b)
{
    return (a.x-o.x)*(b.y-o.y)-(a.y-o.y)*(b.x-o.x);
}
double getarea(point p[],int n)
{
    double area=0;
    for(int i=2;i<n;i++)
    {
        area+=(p[i].x-p[1].x)*(p[i+1].y-p[1].y)-(p[i].y-p[1].y)*(p[i+1].x-p[1].x);
    }
    return area/2.0;
}
double dist(point a,point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
void getline(double &a,double &b,double &c,point x1,point x2)
{
    a=(x1.y-x2.y);
    b=(x2.x-x1.x);
    c=-a*x1.x-b*x1.y;
}
point intersect(double a,double b,double c,point x1,point x2)
{
    double u=fabs(a*x1.x+b*x1.y+c);
    double v=fabs(a*x2.x+b*x2.y+c);
    return point((x1.x*v+x2.x*u)/(u+v),(x1.y*v+x2.y*u)/(u+v));
}
int n,last,now;
point p1[MAXN],p2[MAXN],p3[MAXN];
void cut(double a,double b,double c)
{
    now=0;
    //if(a==0&&b==0&&c<eps){last=0;return;}
    for(int i=1;i<=last;i++)
    {
        if((a*p2[i].x+b*p2[i].y+c)>eps)
        {
            p3[++now]=p2[i];
        }
        else
        {
            if((a*p2[i-1].x+b*p2[i-1].y+c)>eps)
            {
                p3[++now]=intersect(a,b,c,p2[i],p2[i-1]);
            }
            if((a*p2[i+1].x+b*p2[i+1].y+c)>eps)
            {
                p3[++now]=intersect(a,b,c,p2[i],p2[i+1]);
            }
        }
    }
    last=now;
    for(int i=1;i<=last;i++)p2[i]=p3[i];
    p2[last+1]=p3[1];p2[0]=p3[last];
}
inline void GuiZhengHua()
{
    //規整化方向,逆時針變順時針,順時針變逆時針
    for(int i = 1; i <=(n)/2; i++)
      swap(p1[i], p1[n-i]);//標頭檔案加iostream
}
double length=1<<28;
double k1[100+23],k2[100+23],k3[100+23];
int main()
{
    while(scanf("%d",&n)!=-1)
    {
        for(int i=1;i<=n;i++)
        {
            double u,v,w;
            scanf("%lf%lf%lf",&u,&v,&w);
            k3[i]=w;
            k1[i]=u;
            k2[i]=v;
        }
        int m=n;
        for(int i=1;i<=m;i++)
        {
            p2[1]=point(0,0);
            p2[2]=point(0,length);
            p2[3]=point(length,length);
            p2[4]=point(length,0);
            p2[0]=p2[4];
            p2[5]=p2[1];
            last=4;
            double a,b,c;
            for(int j=1;j<=m;j++)
            {
                if(j==i)continue;
                a=(k1[i]-k1[j])/(k1[i]*k1[j]),b=(k2[i]-k2[j])/(k2[i]*k2[j]),c=(k3[i]-k3[j])/(k3[i]*k3[j]);
                cut(a,b,c);
                if(last==0)break;
            }
            if(getarea(p2,last)>=0)puts("No");
            else puts("Yes");
        }
    }
    return 0;
}
本人蒟蒻,如有錯誤,還望指正