hdu1086计算n条线段的交点个数

来源:互联网 发布:js怎么给隐藏域赋值 编辑:程序博客网 时间:2024/06/05 12:39

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1086

题目大意:有n条线段,请输出交点的个数。如果有多条线段相交一点,你应当重复计数。(由示例可以看出,交点为一条线断的端点的非规范相交也符合题意)

解题思路:本题不需要用向量做,太麻烦了。直接用高中解析几何知识做,如果两点在直线两侧,带入直线方程,所得结果异号。即相互跨过,特殊情况(交点为其中一条线段的端点的也包含在内,注意“相互”二字)

代码如下:

#include<stdio.h>
#include<string.h>
#include<math.h>
typedef struct segment
{
    double s1,e1,s2,e2;
}segment;//定义线段
segment a[105];
/*判断一条线段的两端端点是否在另一条的异侧(即跨过另一条线段),端点相交的非规范相交也满足题意*/
int intersect(segment a,segment b)
{
    double x,y;
    x=a.e1-((b.e2-b.e1)*a.s1+(b.e1*b.s2-b.e2*b.s1))/(b.s2-b.s1);
    y=a.e2-((b.e2-b.e1)*a.s2+(b.e1*b.s2-b.e2*b.s1))/(b.s2-b.s1);
    if(x*y<=0)//端点相交的情况体现在等号上
        return 1;
    else
        return 0;
}
int main()
{
    int n,i,j,count;
    while(scanf("%d",&n),n)
    {
        count=0;
        for(i=0;i<n;i++)
        {
            scanf("%lf%lf%lf%lf",&a[i].s1,&a[i].e1,&a[i].s2,&a[i].e2);
        }
        for(i=0;i<n;i++)
        {
            for(j=i+1;j<n;j++)
                if(intersect(a[i],a[j])&&intersect(a[j],a[i]))//判断两条线段是否相互跨过(&&就是相互的意思)
                count++;
        }
        printf("%d\n",count);
    }
return 0;
}


原创粉丝点击