您的位置:首页 > 其它

1212: [视频]【计算几何】判断线段相交(跨立实验)

2017-10-24 21:12 399 查看
1212: [视频]【计算几何】判断线段相交(跨立实验)

时间限制: 1 Sec 内存限制: 128 MB

提交: 122 解决: 60

[提交][状态][讨论版]

题目描述

【题意】

有n条线段(编号为1~n),按1~n的顺序放在二维坐标系上(就是先放1号,再放2号……),

要求输出最上面的那些线段的编号(就是没有其他线段压在它上面的那些线段)

【输入格式】

第一行第一个数n( 1 <= n <= 10000)表示这组数据有n条线段。

下来n行,每行两个坐标,表示第i条线段的两个端点。

【输出格式】

一行。输出最上面的线段的编号(从小到大)。相邻两个编号用空格隔开,最后一个编号没有空格。

【样例1输入】

5

1 1 4 2

2 3 3 1

1 -2.0 8 4

1 4 8 2

3 3 6 -2.0

【样例1输出】

2 4 5

【样例2输入】

3

0 0 1 1

1 0 2 1

2 0 3 1

【样例2输出】

1 2 3

#include<iostream>
#include<cstdio>
using namespace std;
struct Point {
double  x,y;
};
struct Line{
struct Point p1,p2;
};
struct Line L[10000];
int flag[10000];
double cross(struct Point p0,struct Point p1,struct Point p2)
{
double  x1,x2,y1,y2;
x1=p1.x-p0.x;
y1=p1.y-p0.y;
x2=p2.x-p0.x;
y2=p2.y-p0.y;
return x1*y2-x2*y1;
}
bool check(struct Line a,struct Line b)
{
double c1=cross(a.p1,a.p2,b.p1),
c2=cross(a.p1,a.p2,b.p2),
c3=cross(b.p1,b.p2,a.p1),
c4=cross(b.p1,b.p2,a.p2);
if (c1*c2<0&&c3*c4<0) return 1;
if ((cross(a.p1,a.p2,b.p1)==0&&b.p1.x<=max(a.p1.x,a.p2.x)&&b.p1.x>=min(a.p1.x,a.p2.x))||
(cross(a.p1,a.p2,b.p2)==0&&b.p2.x<=max(a.p1.x,a.p2.x)&&b.p2.x>=min(a.p1.x,a.p2.x))||
(cross(b.p1,b.p2,a.p1)==0&&a.p1.x<=max(b.p2.x,b.p1.x)&&a.p1.x>=min(b.p2.x,b.p1.x))||
(cross(b.p1,b.p2,a.p2)==0&&a.p2.x<=max(b.p2.x,b.p1.x)&&a.p2.x>=min(b.p2.x,b.p1.x))) return 1;
return 0;
}
int main()
{
int n,tt=0;
cin>>n;
for (int i=0;i<n;i++)
cin>>L[i].p1.x>>L[i].p1.y>>L[i].p2.x>>L[i].p2.y;
for (int i=0;i<n-1;i++)
for (int j=i+1;j<n;j++)
if (check(L[i],L[j]))
{
flag[i]=1;
break;
}
for (int i=0;i<n;i++)
{
if (!flag[i]&&tt==0)
{
printf("%d",i+1);
tt=1;
}
else if (!flag[i]&&tt==1)
printf(" %d",i+1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: