描述
Stan有n根棍子,他一次一根地将棍子随机地扔在地板上,然后,Stan试图找到在最上面的棍子,也就是没有其他的棍子压在这样的棍子上面,Stan已经注意到,最后扔出的棍子总在最上面,但他想知道所有在最上面的棍子。
输入
首先给出棍子总数n, 1<=n<=100000,接下来是n行,每行4个数,表示每根棍子左右端点的坐标,棍子列表的顺序是Stan扔棍子的顺序。n=0时表示结束。
输出
对每组测试用例,输出一行在最上面的棍子列表,列表顺序按扔棍子的顺序。
输入样例 1
5
1 1 4 2
2 3 3 1
1 -2.0 8 4
1 4 8 2
3 3 6 -2.0
3
0 0 1 1
1 0 2 1
2 0 3 1
0
输出样例 1
Top sticks: 2, 4, 5.
Top sticks: 1, 2, 3.
#include<cstdio>
#include<iostream>
#include<cmath>
#define eps 1e-8
using namespace std;
struct point{//顶点
double x,y;
};
struct stick{//棍
point a,b;
};
stick s[100001];
int check(point A,point B,point C){
double temp=A.x*B.y+B.x*C.y+C.x*A.y-A.x*C.y-B.x*A.y-C.x*B.y;
if(temp<-eps) return -1;
else if(temp>eps) return 1;//逆时针
else return 0;
}
int judgeCross(stick Sc,stick Sd){//判断两个棍子是否相交
int pan1=check(Sc.a,Sc.b,Sd.a)*check(Sc.a,Sc.b,Sd.b);
int pan2=check(Sd.a,Sd.b,Sc.a)*check(Sd.a,Sd.b,Sc.b);
if(pan1==-1 && pan2 == -1) return 2;
else return 1;
}
int main(){
int num;
while(cin>>num && num){
int count=0;
int a[100001];
for(int i=0;i<num;i++){//输入
cin>>s[i].a.x>>s[i].a.y>>s[i].b.x>>s[i].b.y;
}
for(int i=0;i<num-1;i++){
int temp=1;
int j=i+1;
while(temp==1 && j<num) {
temp*=judgeCross(s[i],s[j]);
j++;
}
if(temp==1) {
a[count]=i+1;
count++;
}
}
a[count]=num;
cout<<"Top sticks: ";
for(int i=0;i<=count-1;i++)
cout<<a[i]<<", ";
cout<<a[count]<<"."<<endl;
}
}