HDOJ HDU 1086 You can Solve a Geometry Problem too

来源:互联网 发布:写给大家看的c语言书 编辑:程序博客网 时间:2024/06/06 10:56

HDOJ 1086 You can Solve a Geometry Problem too

题目

点此查看 HDOJ 1086 You can Solve a Geometry Problem too

分类

几何 判断线段交叉

题意

给出 N 个点
求叫点数

题解

逐个扫描 线段是否相交
主要是判断相交的算法
首先看

快速排斥实验
快速排斥实验 图例 
快速排斥实验是一种 快速判断线段是否相交的实验
思想 是 判断以线段做对角线的矩形是否相交 来判断线段是否相交
如上图 可以说明 快速排斥实验不相交的线段一定不相交 但是 相交的的不一定线段相交如中间图
P1 = (x1, y1), P2 = (x2, y2), Q1 = (x3, y3), Q2 = (x4, y4)
算法描述 如 最右方图 可见 矩形不想交 意味着 min(x1,x2) >= max(x3,x4)(P1P2 在 Q1Q2上面) 或者 max(x1,x2) <= min(x3,x4)(P1P2 在 Q1Q2下面) 或者 min(y1,y2) >= max(y3,y4)(P1P2 在 Q1Q2左面)或者 max(y1,y2) <= min(y3,y4)(P1P2 在 Q1Q2下面)
意义 快速判断 只能确定是否不相交

由于 快速排斥实验 不能确定是否相交 所以 引出一个能确定的算法

跨立实验
跨立实验 图示
判断直线是否 可以被另一个相交
有 下式  (P1 - Q1)*(Q2 - Q1) * (Q2 - Q1)* (P2 - Q1) > 0 ,当 (P1 - Q1) * (Q2 - Q1) = 0 表示共线 所以通过跨立实验 的 线段 相交条件为 (P1 - Q1)*(Q2 - Q1) * (Q2 - Q1) * (P2 - Q1) >= 0

 技巧

由于 先进行 快速排斥实验 后 排斥实验
也已用 && 连接

&& 短路
例如 A && B
若 A 为假 则 B 不被执行 

代码

#include <iostream>#define N 101using namespace std;struct Point{    double x;    double y;    friend bool operator==(const Point & p,const Point & q)    {        return (p.x == q.x && p.y == q.y);    }    friend bool operator<(const Point & p,const Point & q)    {        return p.x < q.x;    }};struct Line{    Point p;    Point q;};Line ln[N];bool IsCross(Line u,Line v);int main() {    int mn,ans;    Point cp;    while(cin >> mn && mn)    {        ans = 0;        for(int i = 1;i <= mn;i++)        {            cin >> ln[i].p.x >> ln[i].p.y >> ln[i].q.x >> ln[i].q.y;        }        for(int i = 1;i < mn;i++)            for(int j = i+1;j <= mn;j++)                if(IsCross(ln[i],ln[j]))                    ans++;        cout << ans << endl;    }    return 0;}float Mul(Point a,Point b,Point c){    return (a.x - c.x)*(b.y - c.y)-(b.x - c.x)*(a.y - c.y);}bool IsCross(Line u,Line v){    return (max(u.p.x,u.q.x) >= min(v.p.x,v.q.x)) &&            (max(v.p.x,v.q.x) >= min(u.p.x,u.q.x)) &&            (max(u.p.y,u.q.y) >= min(v.p.y,v.q.y)) &&            (max(v.p.y,v.q.y) >= min(u.p.y,u.q.y)) &&            (Mul(v.p,u.q,u.p) * Mul(u.q,v.q,u.p) >= 0) &&            (Mul(u.p,v.q,v.p) * Mul(v.q,u.q,v.p) >= 0);}