题意:从头到尾输入许多的棍子两端的坐标, 棍子的标号从1到N,按顺序输出没有被覆盖的棍子的标号。
方法:线段判交,先输入的棍子与后面的棍子相交,则先输入的棍子被覆盖掉。
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define eps 1e-8
using namespace std;
struct Point//
{
double x, y;
bool flag;
Point(){};
Point(double x, double y):x(x), y(y){flag = true;}
}a[1000001], b[1000001];
typedef struct Point Vector;//Vector 只是Point别名
//点-点=向量
Vector operator - (Point a, Point b)//
{
return Vector(a.x-b.x, a.y-b.y);
}
//向量a与向量b的叉积
double Cross(Vector a, Vector b)//
{
return a.x*b.y-a.y*b.x;
}
//x=0返回0,x<0返回-1, x>=0返回1
int dcmp(double x)//
{
if (fabs(x) < eps)
return 0;
else
return x < 0 ? -1 : 1;
}
//
bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2)//
{
double c1 = Cross(a2-a1, b1-a1), c2 = Cross(a2-a1, b2-a1),
c3 = Cross(b2-b1, a1-b1), c4 = Cross(b2-b1, a2-b1);
return dcmp(c1*c2)<0 && dcmp(c3*c4)<0;
}
int main()
{
int n;
while (~scanf("%d", &n) && n)
{
for (int i=0; i<n; i++)
{
scanf("%lf%lf%lf%lf", &a[i].x, &a[i].y, &b[i].x, &b[i].y);
a[i].flag = true;
}
for (int i=0; i<n; i++)
for (int j=i+1; j<n; j++)
{
if (SegmentProperIntersection(a[i], b[i], a[j], b[j]))
{
a[i].flag = false;
break;
}
}
printf("Top sticks:");
int m = 0;
for (int i=0; i<n; i++)
if (a[i].flag)
m = i;
for (int i=0; i<n; i++)
if (a[i].flag && i!=m)
printf(" %d,", i+1);
else if (a[i].flag && i==m)
printf(" %d.\n", i+1);
}
return 0;
}