POJ 1755 Triathlon (半平面交)

Triathlon

Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 4733 Accepted: 1166

Description

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

Source

Northeastern Europe 2000

 

 

这题坑了很久,总感觉有问题。

 

精度开到1e-18才过

 

  1 /* ***********************************************
  2 Author        :kuangbin
  3 Created Time  :2013/8/18 19:47:45
  4 File Name     :F:\2013ACM练习\专题学习\计算几何\半平面交\POJ1755_2.cpp
  5 ************************************************ */
  6 
  7 #include <stdio.h>
  8 #include <string.h>
  9 #include <iostream>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <queue>
 13 #include <set>
 14 #include <map>
 15 #include <string>
 16 #include <math.h>
 17 #include <stdlib.h>
 18 #include <time.h>
 19 using namespace std;
 20 const double eps = 1e-18;
 21 int sgn(double x)
 22 {
 23     if(fabs(x) < eps)return 0;
 24     if(x < 0)return -1;
 25     else return 1;
 26 }
 27 struct Point
 28 {
 29     double x,y;
 30     Point(){}
 31     Point(double _x,double _y)
 32     {
 33         x = _x; y = _y;
 34     }
 35     Point operator -(const Point &b)const
 36     {
 37         return Point(x - b.x, y - b.y);
 38     }
 39     double operator ^(const Point &b)const
 40     {
 41         return x*b.y - y*b.x;
 42     }
 43     double operator *(const Point &b)const
 44     {
 45         return x*b.x + y*b.y;
 46     }
 47 };
 48 //计算多边形面积
 49 double CalcArea(Point p[],int n)
 50 {
 51     double res = 0;
 52     for(int i = 0;i < n;i++)
 53         res += (p[i]^p[(i+1)%n]);
 54     return fabs(res/2);
 55 }
 56 //通过两点,确定直线方程
 57 void Get_equation(Point p1,Point p2,double &a,double &b,double &c)
 58 {
 59     a = p2.y - p1.y;
 60     b = p1.x - p2.x;
 61     c = p2.x*p1.y - p1.x*p2.y;
 62 }
 63 //求交点
 64 Point Intersection(Point p1,Point p2,double a,double b,double c)
 65 {
 66     double u = fabs(a*p1.x + b*p1.y + c);
 67     double v = fabs(a*p2.x + b*p2.y + c);
 68     Point t;
 69     t.x = (p1.x*v + p2.x*u)/(u+v);
 70     t.y = (p1.y*v + p2.y*u)/(u+v);
 71     return t;
 72 }
 73 Point tp[110];
 74 void Cut(double a,double b,double c,Point p[],int &cnt)
 75 {
 76     int tmp = 0;
 77     for(int i = 1;i <= cnt;i++)
 78     {
 79         //当前点在左侧,逆时针的点
 80         if(a*p[i].x + b*p[i].y + c < eps)tp[++tmp] = p[i];
 81         else
 82         {
 83             if(a*p[i-1].x + b*p[i-1].y + c < -eps)
 84                 tp[++tmp] = Intersection(p[i-1],p[i],a,b,c);
 85             if(a*p[i+1].x + b*p[i+1].y + c < -eps)
 86                 tp[++tmp] = Intersection(p[i],p[i+1],a,b,c);
 87         }
 88     }
 89     for(int i = 1;i <= tmp;i++)
 90         p[i] = tp[i];
 91     p[0] = p[tmp];
 92     p[tmp+1] = p[1];
 93     cnt = tmp;
 94 }
 95 double V[110],U[110],W[110];
 96 int n;
 97 const double INF = 100000000000.0;
 98 Point p[110];
 99 bool solve(int id)
100 {
101     p[1] = Point(0,0);
102     p[2] = Point(INF,0);
103     p[3] = Point(INF,INF);
104     p[4] = Point(0,INF);
105     p[0] = p[4];
106     p[5] = p[1];
107     int cnt = 4;
108     for(int i = 0;i < n;i++)
109         if(i != id)
110         {
111             double a = (V[i] - V[id])/(V[i]*V[id]);
112             double b = (U[i] - U[id])/(U[i]*U[id]);
113             double c = (W[i] - W[id])/(W[i]*W[id]);
114             if(sgn(a) == 0 && sgn(b) == 0)
115             {
116                 if(sgn(c) >= 0)return false;
117                 else continue;
118             }
119             Cut(a,b,c,p,cnt);
120         }
121     if(sgn(CalcArea(p,cnt)) == 0)return false;
122     else return true;
123 }
124 int main()
125 {
126     //freopen("in.txt","r",stdin);
127     //freopen("out.txt","w",stdout);
128     while(scanf("%d",&n) == 1)
129     {
130         for(int i = 0;i < n;i++)
131             scanf("%lf%lf%lf",&V[i],&U[i],&W[i]);
132         for(int i = 0;i < n;i++)
133         {
134             if(solve(i))printf("Yes\n");
135             else printf("No\n");
136         }
137     }
138     return 0;
139 }

 

 

 

 

 

    原文作者:kuangbin
    原文地址: https://www.cnblogs.com/kuangbin/p/3267057.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞