这是一个计算几何的题目。题意是,按顺序给一系列的线段,问最终哪些线段处在顶端。
只需要穷举判断,当前的线段会与哪些线段有交点即可。也就是暴力求解,但是线段数目N有10的5次方,平方算法是不能过的。这个题
能过的原因是题目描述里面说了,top的stick不会超过1000个。那么修改下暴力的方式题目就能过了。
从小到大枚举每个棍子,判断它是否与后面的棍子相交,如果相交直接把当前棍子的top属性置为false,然后break内层循环。这样就不
会超时了,暴力也是需要技巧的,这句话说的很对啊。
只需要穷举判断,当前的线段会与哪些线段有交点即可。也就是暴力求解,但是线段数目N有10的5次方,平方算法是不能过的。这个题
能过的原因是题目描述里面说了,top的stick不会超过1000个。那么修改下暴力的方式题目就能过了。
从小到大枚举每个棍子,判断它是否与后面的棍子相交,如果相交直接把当前棍子的top属性置为false,然后break内层循环。这样就不
会超时了,暴力也是需要技巧的,这句话说的很对啊。
判断2条线段是否相交的算法直接按照黑书上的模板代码写了,那个模板代码还不错吧。。。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
const int n_max=100005;
const int m_max=1005;
const double eps=1e-6;
bool is_p[n_max];
struct point
{
double x,y;
void init(double tx,double ty)
{
x=tx;
y=ty;
}
};
struct segment
{
point begin,end;
void init(double x1,double y1,double x2,double y2)
{
begin.init(x1,y1);
end.init(x2,y2);
}
void pp()
{
printf("%.2lf %.2lf %.2lf %.2lf\n",begin.x,begin.y,end.x,end.y);
}
}seg[n_max];
int dblcmp(double p)
{
if(fabs(p)<eps)
{
return 0;
}
return p>0?1:-1;
}
double det(double x1,double y1,double x2,double y2)
{
return x1*y2 - x2*y1;
}
double cross(point a,point b,point c)
{
return det(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);
}
bool segcross(segment s1,segment s2)
{
return (dblcmp(cross(s1.begin,s2.begin,s2.end)) ^ dblcmp(cross(s1.end,s2.begin,s2.end))) == -2 &&
(dblcmp(cross(s2.begin,s1.begin,s1.end)) ^ dblcmp(cross(s2.end,s1.begin,s1.end))) == -2;
}
int main()
{
int n;
while(~scanf("%d",&n),n)
{
memset(is_p,0,sizeof(is_p));
double x1,y1,x2,y2;
int i,j;
for(i=1;i<=n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
seg[i].init(x1,y1,x2,y2);
}
queue<int> q;
for(i=1;i<=n;i++)
{
bool b=true;
for(j=i+1;j<=n;j++)
{
if(segcross(seg[i],seg[j]))
{
b=false;
break;
}
}
if(b)
{
q.push(i);
}
}
printf("Top sticks: ");
while(q.size()>1)
{
printf("%d, ",q.front());
q.pop();
}
printf("%d.\n",q.front());
q.pop();
}
return 0;
}