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

一个人往地上扔棍子,相交的话,先扔的就会被压在下面,问最后哪几条棍子(线段)没有被压住?

就是判线段相交了。。从下往上搜,被压住的话就不必判断了,这样的时间复杂度小于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;
}


你可能感兴趣的:(POJ 2653 Pick-up sticks (判线段相交))