判断两条线段相交(跨立实验)

题目描述

【题意】
有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;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值