您的位置:首页 > 其它

POJ 2653 Pick-up sticks (判线段相交)

2012-08-10 12:23 417 查看
一个人往地上扔棍子,相交的话,先扔的就会被压在下面,问最后哪几条棍子(线段)没有被压住?

就是判线段相交了。。从下往上搜,被压住的话就不必判断了,这样的时间复杂度小于O(nlogn)

如果从上往下搜,就是O(nlogn)嗯。。时间复杂度不是很懂啦,谁帮我分析下这个题的复杂度,反正从上往下搜会TLE~

//Memory: 3408K
//Time: 547MS
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
bool top[100005];
struct POINT
{
double x,y;
};
struct LINESEG
{
POINT s,e;
};LINESEG l[100005];
double multiply(POINT sp,POINT ep,POINT op)
{
return((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y));
}
bool intersect(LINESEG u,LINESEG v)
{
return( (max(u.s.x,u.e.x)>=min(v.s.x,v.e.x))&&               //排斥实验
(max(v.s.x,v.e.x)>=min(u.s.x,u.e.x))&&
(max(u.s.y,u.e.y)>=min(v.s.y,v.e.y))&&
(max(v.s.y,v.e.y)>=min(u.s.y,u.e.y))&&
(multiply(v.s,u.e,u.s)*multiply(u.e,v.e,u.s)>=0)&&        //跨立实验
(multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=0));
}
int main()
{
int n;
while(~scanf("%d",&n) && n)
{
int i,j;
for(i=1;i<=n;i++)
{
scanf("%lf %lf %lf %lf",&l[i].s.x,&l[i].s.y,&l[i].e.x,&l[i].e.y);
top[i]=true;
}
for(i=1;i<=n;i++)    //从下往上搜
{
if(top[i])
for(j=i+1;j<=n;j++)
if(intersect(l[i],l[j]))	//是否相交
{
top[i]=false;
break;			//相交则跳出
}
}
bool flag=true;
printf("Top sticks:");
for(i=1;i<=n;i++)
{
if(top[i])
{
if(flag)
{
printf(" %d",i);
flag=false;
}
else
printf(", %d",i);
}
}
printf(".\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  struct