题意:扔了n个棍子,如果某些棍子上边没有被别的棍子压住,则输出这些棍子,按照输入的顺序输出
思路:暴力枚举
做的时候忘了判断 共线但不相交的情况了,wa了好几发
#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
struct Point
{
double x,y;
};
struct Line
{
Point sp,ep;
};
const double precision = 1e-8;
const int MAXN = 100010;
int n;
Line ls[MAXN];
int dblcmp(double d)
{
if(fabs(d) < precision)
return 0;
return d > 0 ? 1:-1;
}
double det(Point a, Point b, Point c)
{
//b.x-a.x,b.y-a.y
//c.x-a.x,c.y-a.y
return (b.x-a.x)*(c.y-a.y) - (c.x-a.x)*(b.y-a.y);
}
int xyCmp(double p, double mini, double maxi)
{
return dblcmp(p-mini)*dblcmp(p-maxi);
}
int betweenCmp(Point a, Point b, Point c)
{
if(fabs(b.x-c.x) > fabs(b.y-c.y))
return xyCmp(a.x,min(b.x,c.x),max(b.x,c.x));
else
return xyCmp(a.y,min(b.y,c.y),max(b.y,c.y));
}
bool intersect(int i, int j)
{
//判断是否相交(不包括顶点重合)
int d1 = dblcmp(det(ls[i].sp,ls[i].ep,ls[j].sp));
int d2 = dblcmp(det(ls[i].sp,ls[i].ep,ls[j].ep));
int d3 = dblcmp(det(ls[j].sp,ls[j].ep,ls[i].sp));
int d4 = dblcmp(det(ls[j].sp,ls[j].ep,ls[i].ep));
if(d1*d2 < 0 && d3*d4 < 0)
return true;
//判断顶点重合的情况 和 共线但不相交的情况
if(d1 == 0 && betweenCmp(ls[j].sp,ls[i].sp,ls[i].ep) <= 0 ||
d2 == 0 && betweenCmp(ls[j].ep,ls[i].sp,ls[i].ep) <= 0 ||
d3 == 0 && betweenCmp(ls[i].sp,ls[j].sp,ls[j].ep) <= 0 ||
d4 == 0 && betweenCmp(ls[i].ep,ls[j].sp,ls[j].ep) <= 0)
return true;
return false;
}
int main()
{
//freopen("in","r",stdin);
bool flag;
while(scanf("%d",&n) && n)
{
for(int i = 1; i <= n; ++i)
scanf("%lf %lf %lf %lf",&ls[i].sp.x,&ls[i].sp.y,&ls[i].ep.x,&ls[i].ep.y);
queue<int> que;
for(int i = 1; i <= n; ++i)
{
flag = true;
for(int j = i+1; j <= n; ++j)
{
if(intersect(i,j))
{
flag = false;
break;
}
}
if(flag)
que.push(i);
}
printf("Top sticks:");
while(que.size() > 1)
{
printf(" %d,",que.front());
que.pop();
}
printf(" %d.\n",que.front());
que.pop();
}
return 0;
}