hdu1086 You can Solve a Geometry Problem too【排斥实验+跨立实验】

来源:互联网 发布:火星时代客观评价知乎 编辑:程序博客网 时间:2024/05/19 02:17

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1086
题意:给你n条线段,让你输出n条线段的交点个数,相同的交点也要计算
解析:由于不用求具体交点,所以可以用跨立实验和排斥实验判断是否有交点
排斥实验:
两条线段各自有一个矩形,若两个矩形相交,则这两条线有可能相交
跨立实验:
通过叉乘判断两条线段是否相交,也就是一条线段的两个端点对另一条线段的叉乘,如果异号则有可能相交

#include <cmath>#include <algorithm>#include <iostream>#include <cstdio>#include <vector>#include <cstring>using namespace std;const int maxn = 1e5;const double eps = 1e-5;struct point{    double x;    double y;    point() {}    point(double _x,double _y)    {        x = _x;        y = _y;    }};struct line{    point a;    point b;}a[maxn];double x_mul(point p0,point p1,point p2){    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}bool judge(line p1,line p2){    //排斥实验    bool flag1 = max(p1.a.x,p1.b.x)>=min(p2.a.x,p2.b.x)&&                 max(p2.a.x,p2.b.x)>=min(p1.a.x,p1.b.x)&&                 max(p1.a.y,p1.b.y)>=min(p2.a.y,p2.b.y)&&                 max(p2.a.y,p2.b.y)>=min(p1.a.y,p1.b.y);    //跨立实验    bool flag2 = (x_mul(p1.a,p2.a,p2.b)*x_mul(p1.b,p2.a,p2.b)<=0)&&                 (x_mul(p2.a,p1.a,p1.b)*x_mul(p2.b,p1.a,p1.b)<=0);    return flag1&&flag2;}int main(void){    int n;    while(~scanf("%d",&n)&&n)    {        for(int i=0;i<n;i++)        {            double x1,y1,x2,y2;            scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);            a[i].a = point(x1,y1);            a[i].b = point(x2,y2);        }        int ans = 0;        for(int i=0;i<n;i++)        {            for(int j=i+1;j<n;j++)            {                if(judge(a[i],a[j]))                    ans++;            }        }        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击