【发布时间】:2016-11-12 19:53:05
【问题描述】:
有 N 个线段,水平或垂直。现在我需要找出每条线段的交点总数和交点总数。 N 可以达到 100000。我试着检查每一对线。答案是正确的,但我需要减少它所花费的时间。
这是我的代码:
using namespace std;
typedef struct Point
{
long long int x;
long long int y;
} ;
bool fun(Point p0, Point p1, Point p2, Point p3)
{
double s1_x, s1_y, s2_x, s2_y;
s1_x = p1.x - p0.x; s1_y = p1.y - p0.y;
s2_x = p3.x - p2.x; s2_y = p3.y - p2.y;
double s, t;
s = (-s1_y * (p0.x - p2.x) + s1_x * (p0.y - p2.y)) / (-s2_x * s1_y + s1_x * s2_y);
t = ( s2_x * (p0.y - p2.y) - s2_y * (p0.x - p2.x)) / (-s2_x * s1_y + s1_x * s2_y);
if (s >= 0 && s <= 1 && t >= 0 && t <= 1)
{
return 1; // Collision detected
}
return 0; // No collision
}
int main()
{
long long int n // number of line segments;
Point p[n],q[n]; // to store end points of line segments
for( long long int i=0;i<n;i++)
{
// line segments is defined by 2 points P(x1,y1) and Q(x2,y2)
p[i].x=x1;
p[i].y=y1;
q[i].x=x2;
q[i].y=y2;
}
for( long long int i=0;i<n-1;i++)
{
for( long long int j=i+1;j<n;j++)
{
if(fun(p[i],q[i],p[j],q[j]))
count++;
}
}
return 0;
}
有人可以帮我降低这个程序的时间复杂度吗?
【问题讨论】:
-
如果它们是水平的或垂直的,那么检查交叉点比检查任意线容易得多(如您的方法)。此外,首先按 x/y 坐标对线条进行排序。然后你知道可能的交叉点必须在哪个区域。更复杂的方法是使用分段树或区间树。
-
同一个老师还是同一个比赛? stackoverflow.com/questions/40570886/…
-
@MBoI 不认识他,但问题似乎相似,但我们的方法非常不同。
-
@Spektre 感谢您的帮助。
标签: c++ algorithm time-complexity line-intersection