POJ 1755-Triathlon(半平面交-铁人三项)
2017-04-17 15:12
477 查看
Triathlon
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
Sample Output
Source
Northeastern Europe 2000
白书上的题,白书上的代码。
题目意思就是说给出N个人铁人三项的各项速度,他们路程可以被统一的任意给定,判断哪些选手可能获得冠军(不能并列)。
设总长为1,三项长度分别是x,y,1-x-y,则利用时间=路程/速度公式,抽象出Ax+By+C>0的不等式,计算与其他人的所有半平面是否全部为空,若是则可能获胜。
道理我都懂,我就是不知道为什么插入直线上一点(这里取截距)的时候还判断了一下斜率,毕竟不判断也可以AC啊,难道和效率有关Orz?
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 6958 | Accepted: 1807 |
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
白书上的题,白书上的代码。
题目意思就是说给出N个人铁人三项的各项速度,他们路程可以被统一的任意给定,判断哪些选手可能获得冠军(不能并列)。
设总长为1,三项长度分别是x,y,1-x-y,则利用时间=路程/速度公式,抽象出Ax+By+C>0的不等式,计算与其他人的所有半平面是否全部为空,若是则可能获胜。
道理我都懂,我就是不知道为什么插入直线上一点(这里取截距)的时候还判断了一下斜率,毕竟不判断也可以AC啊,难道和效率有关Orz?
// LA2218 Triathlon // Rujia Liu #include<cstdio> #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; Vector operator + (const Vector& A, const Vector& B) { return Vector(A.x+B.x, A.y+B.y); } Vector operator - (const Point& A, const Point& B) { return Vector(A.x-B.x, A.y-B.y); } Vector operator * (const Vector& A, double p) { return Vector(A.x*p, A.y*p); } double Dot(const Vector& A, const Vector& B) { return A.x*B.x + A.y*B.y; } double Cross(const Vector& A, const Vector& B) { return A.x*B.y - A.y*B.x; } double Length(const Vector& A) { return sqrt(Dot(A, A)); } Vector Normal(const Vector& A) { double L = Length(A); return Vector(-A.y/L, A.x/L); } double PolygonArea(vector<Point> p) { int n = p.size(); double area = 0; for(int i = 1; i < n-1; i++) area += Cross(p[i]-p[0], p[i+1]-p[0]); return area/2; } // 有向直线。它的左边就是对应的半平面 struct Line { Point P; // 直线上任意一点 Vector v; // 方向向量 double ang; // 极角,即从x正半轴旋转到向量v所需要的角(弧度) Line() {} Line(Point P, Vector v):P(P),v(v) { ang = atan2(v.y, v.x); } bool operator < (const Line& L) const { return ang < L.ang; } }; // 点p在有向直线L的左边(线上不算) bool OnLeft(const Line& L, const Point& p) { return 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; } const double INF = 1e8; const double eps = 1e-6; // 半平面交主过程 vector<Point> HalfplaneIntersection(vector<Line> L) { int n = L.size(); sort(L.begin(), L.end()); // 按极角排序 int first, last; // 双端队列的第一个元素和最后一个元素的下标 vector<Point> p(n); // p[i]为q[i]和q[i+1]的交点 vector<Line> q(n); // 双端队列 vector<Point> ans; // 结果 q[first=last=0] = L[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(fabs(Cross(q[last].v, q[last-1].v)) < eps) // 两向量平行且同向,取内侧的一个 { 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 ans; // 空集 p[last] = GetLineIntersection(q[last], q[first]); // 计算首尾两个半平面的交点 // 从deque复制到输出中 for(int i = first; i <= last; i++) ans.push_back(p[i]); return ans; } const int maxn = 100 + 10; int V[maxn], U[maxn], W[maxn]; int main() { #ifdef ONLINE_JUDGE #else freopen("G:/cbx/read.txt","r",stdin); //freopen("G:/cbx/out.txt","w",stdout); #endif int n; 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 ok = 1; double k = 10000; vector<Line> L; 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; // x/V[i]+y/U[i]+(1-x-y)/W[i] < x/V[j]+y/U[j]+(1-x-y)/W[j] // ax+by+c>0 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.push_back(Line(P, v)); } if(ok) { // x>0, y>0, x+y<1 ==> -x-y+1>0 L.push_back(Line(Point(0, 0), Vector(0, -1))); L.push_back(Line(Point(0, 0), Vector(1, 0))); L.push_back(Line(Point(0, 1), Vector(-1, 1))); vector<Point> poly = HalfplaneIntersection(L); if(poly.empty()) ok = 0; } if(ok) printf("Yes\n"); else printf("No\n"); } } return 0; }
相关文章推荐
- poj 1755 Triathlon 半平面交
- poj 1755 Triathlon(半平面交应用)
- 【半平面交】 POJ 1755 Triathlon
- poj 1755 Triathlon(半平面交解可行域)
- POJ 1755 Triathlon(n^2 半平面交, 两点式和参数式直线求交点)
- POJ 1755 Triathlon 半平面交
- POJ 1755 Triathlon 半平面交
- [POJ][1755][Triathlon][半平面交]
- POJ 1755 Triathlon (半平面交)
- POJ 1755 Triathlon 半平面交
- POJ 1755 Triathlon 半平面交
- poj 1755 Triathlon(半平面交解不等式)
- POJ 1755 Triathlon(半平面交解不等式)
- POJ 1755 Triathlon 半平面交
- POJ 1755 Triathlon [半平面交 线性规划]
- poj 1755 Triathlon 半平面交判断不等式是否有解
- Poj 1755 Triathlon (半平面交求可行域)
- POJ 1755 Triathlon(线性规划の半平面交)
- POJ 1755 Triathlon(半平面交)
- BZOJ 3800 Saber VS Lancer/POJ 1755 Triathlon 半平面交