Description
Input
Output
The picture to the right below illustrates the first case from input.
Sample Input
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
Sample Output
Top sticks: 2, 4, 5. Top sticks: 1, 2, 3.
Hint
Source
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
#define maxn 100005
struct point
{
double x,y;
};
struct line
{
point sp,ep;
}L[maxn];
int n;
bool used[maxn];
double x_multi(point p1,point p2,point p3)
{
return (p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y);
}
bool Onsegment(point p1,point p2,point p3)
{
double min_x=min(p1.x,p2.x);
double min_y=min(p1.y,p2.y);
double max_x=max(p1.x,p2.x);
double max_y=max(p1.y,p2.y);
if(p3.x>=min_x&&p3.x<=max_x&&p3.y>=min_y&&p3.y<=max_y)
return true;
return false;
}
bool Is_intersected(point p1,point p2,point p3,point p4)
{
double d1=x_multi(p1,p2,p3);
double d2=x_multi(p1,p2,p4);
double d3=x_multi(p3,p4,p1);
double d4=x_multi(p3,p4,p2);
if(d1*d2<0.0&&d3*d4<0.0)
return true;
if(d1==0.0&&Onsegment(p1,p2,p3))
return true;
if(d2==0.0&&Onsegment(p1,p2,p4))
return true;
if(d3==0.0&&Onsegment(p3,p4,p1))
return true;
if(d4==0.0&&Onsegment(p3,p4,p2))
return true;
return false;
}
int main()
{
while(scanf("%d",&n),n)
{
int i,j;
for(i=1;i<=n;i++)
scanf("%lf%lf%lf%lf",&L[i].sp.x,&L[i].sp.y,&L[i].ep.x,&L[i].ep.y);
memset(used,false,sizeof(used));
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
if(Is_intersected(L[i].sp,L[i].ep,L[j].sp,L[j].ep))
{
used[i]=true;
break;
}
printf("Top sticks: ");
for(i=1;i<=n;i++)
if(!used[i])
{
if(i<n)
printf("%d, ",i);
else
printf("%d.\n",i);
}
}
return 0;
}