具体分析参考LRJ大蓝书第四章 本题使用到半平面交
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cstring>
#include<cmath>
#define fabs(x) ((x) < 0 ? (-(x)) : (x))
#define SF scanf
#define PF printf
using namespace std;
typedef long long LL;
const int MAXN = 100;
const int INF = 1234567890;
const double L = 100000.0;
const double EPS = 1e-8;
struct Vector {
double x, y;
Vector () {}
Vector (double xx, double yy) { x = xx; y = yy; }
Vector (double rad) { x = cos(rad); y = sin(rad); }
double len() const { return sqrt(x*x + y*y); }
Vector operator + (const Vector &b) const {
return Vector(x + b.x, y + b.y);
}
Vector operator - (const Vector &b) const {
return Vector(x - b.x, y - b.y);
}
Vector operator * (const double &b) const {
return Vector(x * b, y * b);
}
Vector operator / (const double &b) const {
return Vector(x / b, y / b);
}
};
typedef Vector Point, Angle;
struct Line {
Point P;
Vector v;
double ang;
Line () {}
Line (Point A, Vector B) : P(A), v(B) { ang = atan2(v.y, v.x); }
bool operator < (const Line &L) const {
return ang < L.ang;
}
};
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;
}
Vector GetAngle(const Vector &a, const Vector &b) {
double l1 = a.len(), l2 = b.len();
return Vector(Dot(a, b) / l1 / l2, Cross(a, b)/ l1 / l2);
}
Vector Rotate(const Vector &a, const Angle &angle) {
return Vector(a.x * angle.x - a.y * angle.y, a.x * angle.y + a.y * angle.x);
}
Point GetIntersection(const Point &a, const Point &b, const Point &c, const Point &d)
{
double t = 1.0 * Cross(d - a, c - a) / Cross(b - a, d - c);
return a + (b - a) * fabs(t);
}
Point GetIntersection(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 GetDirection(const Point &a, const Point &b, const Point &c)
{
// -1 逆时针
Vector v = b - a, B = c - a;
double flag = Cross(B, v);
if(flag < 0) return -1; if(flag > 0) return 1; return 0;
}
bool OnLeft(Line L, Point P) {
return Cross(L.v, P-L.P) > 0;
}
Point p[MAXN+10];
Line q[MAXN+10];
bool HalfPlaneIntersection(Line *L, int N, Point *Ans)
{
sort(L, L+N);
int F, R;
//Point *p = new Point[N]; // p[i]为q[i+1]和q[i]的交点
//Line *q = new Line[N]; // p左闭右开 q左闭右闭
q[F=R=0] = L[0];
for(int i = 1; i < N; i++) {
while(F < R && !OnLeft(L[i], p[R-1])) R--;
while(F < R && !OnLeft(L[i], p[F])) F++;
q[++R] = L[i];
if(fabs(Cross(q[R].v, q[R-1].v)) < EPS) {
R--;
if(OnLeft(q[R], L[i].P)) q[R] = L[i];
}
if(F < R) p[R-1] = GetIntersection(q[R-1], q[R]);
//if(F < R) p[R-1] = GetIntersection(q[R-1].P, q[R-1].P+q[R-1].v, q[R].P, q[R].P+q[R].v);
}
while(F < R && !OnLeft(q[F], p[R-1])) R--;
if(R - F < 2) return 0;
p[R] = GetIntersection(q[F], q[R]);
//p[R] = GetIntersection(q[F].P, q[F].P+q[F].v, q[R].P, q[R].P+q[R].v);
int CNT = 0;
for(int i = F; i <= R; i++) Ans[CNT++] = p[i];
return CNT;
}
int v1[MAXN+10], v2[MAXN+10], v3[MAXN+10], n;
Line Q[MAXN+10];
Point Ans[MAXN+10];
int Speed_cmp(int a, int b)
{
if(v1[a] <= v1[b] && v2[a] <= v2[b] && v3[a] <= v3[b]) return -1;
if(v1[a] >= v1[b] && v2[a] >= v2[b] && v3[a] >= v3[b]) return 1;
return 0;
}
int main()
{
SF("%d", &n);
for(int i = 1; i <= n; i++) SF("%d%d%d", &v1[i], &v2[i], &v3[i]);
for(int i = 1; i <= n; i++) {
bool ok = true;
int cnt = 0;
for(int j = 1; j <= n; j++)
if(i != j) {
if(Speed_cmp(i, j) > 0) continue;
else if(Speed_cmp(i, j) < 0) { ok = false; break; }
// Ax + By + C
double A = (L / v1[j] - L / v3[j]) - (L / v1[i] - L / v3[i]);
double B = (L / v2[j] - L / v3[j]) - (L / v2[i] - L / v3[i]);
double C = L / v3[j] - L / v3[i];
Vector v = Vector(B, -A);
Point P;
if(fabs(A) > fabs(B)) P = Point(-C / A, 0);
else P = Point(0, -C / B);
Q[cnt++] = Line(P, v);
}
if(ok) {
Q[cnt++] = Line(Point(0, 0), Vector(0, -1));
Q[cnt++] = Line(Point(0, 0), Vector(1, 0));
Q[cnt++] = Line(Point(0, 1), Vector(-1, 1));
if(!HalfPlaneIntersection(Q, cnt, Ans)) ok = false;
}
if(ok) puts("Yes");
else puts("No");
}
}