题目大意:
按顺序扔下n根棍子,给出棍子的端点坐标,求没有被压住的棍子的序号。
通过快速排斥实验和跨立实验两个方法,判断线段间的关系。
AC代码:
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
struct stick{
double x1,x2,y1,y2;
stick (){}; //构造函数
stick(int xx1,int xx2,int yy1,int yy2){
x1 = xx1;
x2 = xx2;
y1 = yy1;
y2 = yy2;
}
}s[110000];
bool rectangle_is_cross(stick a,stick b){ //快速排斥实验
if(max(a.x1,a.x2) >= min(b.x1,b.x2) && min(a.x1,a.x2) <= max(b.x1,b.x2) &&
max(a.y1,a.y2) >= min(b.y1,b.y2) && min(a.y1,a.y2) <= max(b.y1,b.y2))
return 1;
else return 0;
}
bool is_cross(stick a,stick b){ //跨立实验
if(((a.x1-b.x1)*(b.y2-b.y1)-(a.y1-b.y1)*(b.x2-b.x1))*
((b.x2-b.x1)*(a.y2-b.y1)-(b.y2-b.y1)*(a.x2-b.x1)) > 0)
return 1;
else return 0;
}
int main(void){
int n,cover[110000];
while(cin>>n && n){
memset(cover,0,sizeof(cover));
for(int i=0;i<n;++i){
// cin>>s[i].x1>>s[i].y1>>s[i].x2>>s[i].y2;
// cout<<s[i].x1<<s[i].y1<<s[i].x2<<s[i].y2<<endl;
scanf("%lf %lf %lf %lf",&s[i].x1,&s[i].y1,&s[i].x2,&s[i].y2);
}
for(int i=0;i<n;++i){
for(int j=i+1;j<n;++j){
if(!cover[i]){ //未覆盖
if(rectangle_is_cross(s[i],s[j])){ //矩阵相交
if(is_cross(s[i],s[j]) && is_cross(s[j],s[i])){ //相互跨立
cover[i] = 1; //i覆盖j
break;
}
}
}
}
}
cout<<"Top sticks:";
bool flag = 1;
for(int i=0;i<n;++i){
if(!cover[i]){
if(flag){
cout<<' '<<i+1;
flag = 0;
}
else cout<<", "<<i+1;
}
}
cout<<'.'<<endl;
}
return 0;
}