poj 2653 Pick-up sticks 线段相交

题目链接

题意

依次扔(n)根小棒,输出没有被压着的小棒的编号。

思路

对每根小棒,判断它和之后扔的小棒有没有交点。一旦有,就将其排除掉。

虽然算法是(O(n^2)的),但是数据水呀~

注意:如果对于每根小棒去判断它有没有压着前面的小棒,将前面被压着的小棒排除掉,这种写法会(T)

Code

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#define inf 1e200
#define eps 1e-6
#define maxn 100010
using namespace std;
typedef long long LL;
struct Point {
    double x, y;
    Point(double _x=0, double _y=0) : x(_x), y(_y) {}
    Point operator + (const Point& b) const {
        return Point(x+b.x, y+b.y);
    }
    Point operator - (const Point& b) const {
        return Point(x-b.x, y-b.y);
    }
    double operator * (const Point& b) const {
        return x*b.x + y*b.y;
    }
    double operator ^ (const Point& b) const {
        return x*b.y - y*b.x;
    }
};
struct Seg {
    Point s, e;
    Seg(Point _s, Point _e) : s(_s), e(_e) {}
    Seg() {}
}seg[maxn];
int sgn(double x) {
    if (fabs(x) < eps) return 0;
    if (x > 0) return 1;
    return -1;
}
double xmult(Point s, Point e, Point b) {
    return (s-b) ^ (e-b);
}
bool intersect(Seg u, Seg v) {
    return (max(u.s.x,u.e.x) >= min(v.s.x,v.e.x)) &&
        (max(v.s.x,v.e.x) >= min(u.s.x,u.e.x)) &&
        (max(u.s.y,u.e.y) >= min(v.s.y,v.e.y)) &&
        (max(v.s.y,v.e.y) >= min(u.s.y,u.e.y)) &&
        (sgn(xmult(v.s,u.e,u.s)) * sgn(xmult(u.e,v.e,u.s)) >= 0) &&
        (sgn(xmult(u.s,v.e,v.s)) * sgn(xmult(v.e,u.e,v.s)) >= 0);
}
int n, ans[1010];
bool out[maxn];
void work() {
    memset(out, 0, sizeof out);
    for (int i = 1; i <= n; ++i) {
        double x1,y1,x2,y2;
        scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
        seg[i] = Seg(Point(x1, y1), Point(x2, y2));
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = i+1; j <= n; ++j) {
            if (intersect(seg[i], seg[j])) { out[i] = true; break; }
        }
    }
    int tot = 0;
    for (int i = 1; i <= n; ++i) if (!out[i]) ans[tot++] = i;
    printf("Top sticks:");
    for (int i = 0; i < tot-1; ++i) printf(" %d,", ans[i]); printf(" %d.
", ans[tot-1]);
}
int main() {
    while (scanf("%d", &n) != EOF && n) work();
    return 0;
}

原文地址:https://www.cnblogs.com/kkkkahlua/p/7636151.html