您的位置:首页 > 其它

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

2017-02-27 21:24 357 查看
题目链接: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: