问题
Description
线段求交即给定一组线段求出这些线段的相交情况,它是计算几何的基础问题之一,有着广泛的应用.
Input
第一行为一个正整数n表示线段的个数(n<=10000)
第二行到第n+1行每行包括4个正整数x1,y1,x2,y2, (0 <= x1,y1,x2,y2 <= 1000) x1,x2表示线段两端点的横坐标,y1,y2表示线段两端点的纵坐标
注意线段的两端点可能重合 即(x1,y1)有可能等于(x2,y2)
Output
一个正整数k, 表示相交的线段对数,这里只要两线段有接触即为相交.数据保证k<=100000.
Sample Input
8
10 13 20 56
37 60 40 7
87 57 113 5
96 16 125 51
171 4 231 4
200 4 211 43
268 36 354 36
283 4 314 36
Sample Output
3
TLE代码
#include
#define N 10002
/**
算法适用于整形点,不适用于浮点型
**/
typedef struct Point
{
int x;
int y;
}Point;
double min(int x, int y)
{
return xy?x:y;
}
//排斥实验
bool IsRectCross(const Point &p1,const Point &p2,const Point &q1,const Point &q2)
{
bool ret = min(p1.x,p2.x) <= max(q1.x,q2.x) &&
min(q1.x,q2.x) <= max(p1.x,p2.x) &&
min(p1.y,p2.y) <= max(q1.y,q2.y) &&
min(q1.y,q2.y) <= max(p1.y,p2.y);
return ret;
}
//跨立判断
bool IsLineSegmentCross(const Point &P1,const Point &P2,const Point &Q1,const Point &Q2)
{
if(
((Q1.x-P1.x)*(Q1.y-Q2.y)-(Q1.y-P1.y)*( Q1.x-Q2.x)) * ((Q1.x-P2.x)*(Q1.y-Q2.y)-(Q1.y-P2.y)*(Q1.x-Q2.x)) < 0 ||
((P1.x-Q1.x)*(P1.y-P2.y)-(P1.y-Q1.y)*(P1.x-P2.x)) * ((P1.x-Q2.x)*(P1.y-P2.y)-(P1.y-Q2.y)*( P1.x-P2.x)) < 0
)
return true;
else
return false;
}
int main() //O(n^2)
{
int n,i,j;
Point arr[N][2];
int count;
while(scanf("%d",&n)!=EOF && n!=0)//第一行为一个正整数n表示线段的个数(n<=10000)
{
count=0;
for(i=1;i<=n;i++)
scanf("%d %d %d %d", &arr[i][0].x, &arr[i][0].y, &arr[i][1].x,&arr[i][1].y); //第二行到第n+1行每行包括4个正整数x1,y1,x2,y2, (0 <= x1,y1,x2,y2 <= 1000)
for(i=1; i<=n; i++)
for(j=i+1; j<=n; j++)
if(IsRectCross(arr[i][0],arr[i][1],arr[j][0],arr[j][1])&&IsLineSegmentCross(arr[i][0],arr[i][1],arr[j][0],arr[j][1]))
count++;
printf("%d\n",count);
}
return 0;
}
/**
8
10 13 20 56
37 60 40 7
87 57 113 5
96 16 125 51
171 4 231 4
200 4 211 43
268 36 354 36
283 4 314 36
**/
/**************************************************************
Problem: 1171
User: cld378632668
Language: C++
Result: Time Limit Exceed
****************************************************************/
AC 代码
#include
#include
#define p(x1,y1,x2,y2,a,b) ((y2-y1)*(a-x1)+(y1-b)*(x2-x1))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
#endif // ONLINE_JUDGE
int n,m;
scanf("%d",&n);
int x1[n+1],y1[n+1],x2[n+1],y2[n+1],i,j,a,b,c,d,sum=0;
for (i=1;i<=n;i++)
scanf("%d%d%d%d",x1+i,y1+i,x2+i,y2+i);
for (i=1;i=min(x1[j],x2[j]) && max(x1[j],x2[j])>=min(x1[i],x2[i]) && max(y1[i],y2[i])>=min(y1[j],y2[j]) && max(y1[j],y2[j])>=min(y1[i],y2[i]))
sum++;
}
else
{
if ((a<=0 && b>=0 || a>=0 && b<=0) && (c<=0 && d>=0 || c>=0 && d<=0))
{
sum++;
//printf("%d %d\n",i,j);
}
}
}
printf("%d\n",sum);
return 0;
}