题目描述
【题意】
有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输出】
有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
主要运用了叉积,
首先a向量叉乘b向量=|a|b|sinC
然后只要码代码就好了
#include<iostream>
#include<cstdio>
#include<math.h>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<vector>
using namespace std;
int n;
typedef struct Node{
double x1,y1,x2,y2;
};
typedef struct No{
double x,y;
};
Node node[10000+10];
double chaji(No n0,No n1,No n2){
return (n1.x-n0.x)*(n2.y-n0.y)-(n2.x-n0.x)*(n1.y-n0.y);
}
int check(int i,int j){
No n1,n2,n3,n4;
n1.x=node[i].x1;
n1.y=node[i].y1;
n2.x=node[i].x2;
n2.y=node[i].y2;
n3.x=node[j].x1;
n3.y=node[j].y1;
n4.x=node[j].x2;
n4.y=node[j].y2;
if(chaji(n1,n2,n3)*(chaji(n1,n2,n4))<0&&(chaji(n3,n4,n1)*(chaji(n3,n4,n2))<0)) return 1;
if((chaji(n1,n2,n3)==0&&n3.x<=max(n1.x,n2.x)&&n3.x>=min(n1.x,n2.x)) ||
(chaji(n1,n2,n4)==0&&n4.x<=max(n1.x,n2.x)&&n4.x>=min(n1.x,n2.x)) ||
(chaji(n1,n4,n3)==0&&n1.x<=max(n3.x,n4.x)&&n1.x>=min(n3.x,n4.x)) ||
(chaji(n2,n4,n3)==0&&n2.x<=max(n3.x,n4.x)&&n2.x>=min(n3.x,n4.x)) ) return 1;
return 0;
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
scanf("%lf%lf%lf%lf",&node[i].x1,&node[i].y1,&node[i].x2,&node[i].y2);
}
int v[10000+10]={0};
for(int i=0;i<n-1;i++){
for(int j=i+1;j<n;j++){
if(check(i,j)){
v[i]=1;
break;
}
}
}
int out[10000+10],len=0;
for(int i=0;i<n;i++) if(v[i]==0) out[len++]=i+1;
cout<<out[0];
for(int i=1;i<len;i++) printf(" %d",out[i]);
return 0;
}