您的位置:首页 > 其它

POJ 1755 Triathlon(n^2 半平面交, 两点式和参数式直线求交点)

2014-07-23 22:26 507 查看
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;

struct Point {
double x, y;
Point(){}
Point(double _x, double _y) { x = _x, y = _y;}
};

const int maxn = 110;
double u[maxn], v[maxn], w[maxn];
const double inf = 1e11, eps = 1e-8;
Point poly[maxn];
int pcnt;

int sgn(double x) { return (x < -eps) ? -1 : (x > eps);}

Point intersect(Point p1, Point p2, double a, double b, double c)
{
double u = fabs(a*p1.x + b*p1.y + c);
double v = fabs(a*p2.x + b*p2.y + c);
Point t;
t.x = (p1.x*v + p2.x*u)/(u+v);
t.y = (p1.y*v + p2.y*u)/(u+v);
return t;
}

void cut(double a, double b, double c)
{
Point tp[maxn];
int tcnt = 0;
for (int i = 1; i <= pcnt; i++) {
if (sgn((a * poly[i].x + b * poly[i].y + c) <= 0)) {
tp[++tcnt] = poly[i];
} else {
if (sgn(a * poly[i-1].x + b * poly[i-1].y + c) < 0)
tp[++tcnt] = intersect(poly[i-1], poly[i], a, b, c);
if (sgn(a * poly[i+1].x + b * poly[i+1].y + c) < 0)
tp[++tcnt] = intersect(poly[i], poly[i+1], a, b, c);
}
}
pcnt = tcnt;
for (int i = 1; i <= tcnt; i++)
poly[i] = tp[i];
poly[0] = poly[pcnt];
poly[pcnt+1] = poly[1];
}

int main()
{
int n;

while (~scanf("%d", &n)) {
for (int i = 0; i < n; i++)
scanf("%lf%lf%lf", &u[i], &v[i], &w[i]);
for (int i = 0; i < n; i++) {
poly[1] = poly[5] = Point(0,0);
poly[2] = Point(inf, 0);
poly[3] = Point(inf, inf);
poly[4] = poly[0] = Point(0, inf);
pcnt = 4;
for (int j = 0; j < n; j++) {
if (i == j) continue;
if (u[j] >= u[i] && v[j] >= v[i] && w[j] >= w[i]) {
pcnt = 0;
break;
}
double a = (u[j] - u[i]) / (u[j] * u[i]);
double b = (v[j] - v[i]) / (v[j] * v[i]);
double c = (w[j] - w[i]) / (w[j] * w[i]);
cut(a, b, c);
if (pcnt < 3)
break;
}
puts(pcnt > 2 ? "Yes" : "No");
}
}

return 0;
}


感觉就是处理成不等式然后求半平面交,但是用 nlogn 的那个模板过不去,后来看网上有人说那种做法会有精度损失,于是看着别人的代码学习了 n^2 的方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: