Segments POJ

  • 题解:问题转化很重要,表面上是求是否存在一条直线,然后让所有线段在其投影上有公共部分,其实就是问是否存在一条直线可以穿过所有线段。本质上所有的问题都可以通过遍历点来解决,所以就是遍历每两个点,形成一条直线,然后判每条边是否在两边。
  • 代码:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <vector>

using namespace std;
typedef  double ld;
const ld eps = 1e-8;
const int N = 50009;
struct Point {
    ld x, y;
    Point(ld X = 0, ld Y = 0) { x = X, y = Y; }
    Point operator-(Point a) { return Point(x - a.x, y - a.y); }
    Point operator+(Point a) { return Point(x + a.x, y + a.y); }
    ld operator*(Point a) { return x * a.y - y * a.x; }
    ld dis() {
        return sqrt(x * x + y * y);
    }
} p[N];
int dcmp(ld a, ld b) {
    if (fabs(a-b)< eps)return 0;
    else if (a > b)return 1;
    else return -1;
}
typedef Point Vector;
struct Line {
    Point p1, p2;
}L[N];
int cnt[N];
int n, m;
Line l[N];
void solve() {
    bool first = 1;
    scanf("%d", &n);
    if (n == 0) return;
    int p_cnt = 0;
    for (int i = 1; i <= n; i++) {
        ld x1, x2;
        scanf("%lf%lf", &x1, &x2);p_cnt++;
        p[p_cnt].x = x1, p[p_cnt].y = x2;
        scanf("%lf%lf", &x1, &x2);
        p_cnt++;
        p[p_cnt].x = x1, p[p_cnt].y = x2;
        L[i] = {p[p_cnt-1], p[p_cnt]};
    }
    for (int i = 1; i <= p_cnt; i ++) {
        for (int j = i + 1; j <= p_cnt; j ++) {
            bool f = 1;
            Vector v = p[j] - p[i];
            if (dcmp(v.dis(), 0) == 0)continue;
            for (int k = 1; k <= n; k ++) {
                Vector v1 = L[k].p1 - p[i];
                Vector v2 = L[k].p2 - p[i];
                int d1 = dcmp(v * v1, 0);
                int d2 = dcmp(v * v2, 0);
                if (d1 * d2 <= 0) {
                    continue;
                } else {f = 0;break;}
            }
            if (f) {puts("Yes!");return;}
        }
    }
    if (n == 1 || n == 2) puts("Yes!");
    else
    puts("No!");
}
signed main() {
    //ios::sync_with_stdio(0);
    int t = 1;scanf("%d", &t);
    while (t--) {
        solve();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Xiao-yan/p/14640197.html