POJ 2653 Pick-up sticks
2012-03-28 10:19 咆哮的马甲 阅读(207) 评论(0) 编辑 收藏 举报考察点在于如何判断两线段相交(快速排斥+跨立),之前使用链表结构超时了,后来用vector实现。
判断线段相交的办法,这篇文章讲的很明白。http://324012406.iteye.com/blog/738318
#include <iostream>
#include <vector>
using namespace std;
typedef struct Coordinate
{
Coordinate(double _x, double _y)
:x(_x),y(_y)
{
}
double x;
double y;
} Coordinate;
typedef struct Stick
{
Stick()
:index(0),start(0.0,0.0),end(0.0,0.0)
{
}
Stick(int i, double x1, double y1, double x2, double y2)
:index(i),start(x1,y1),end(x2,y2)
{
}
int index;
Coordinate start;
Coordinate end;
} Stick;
inline bool isRectCrossed(const Stick& s1,const Stick& s2)
{
// rect1
double rect1_min_x = min(s1.start.x,s1.end.x);
double rect1_max_x = max(s1.start.x,s1.end.x);
double rect1_min_y = min(s1.start.y,s1.end.y);
double rect1_max_y = max(s1.start.y,s2.end.y);
// rect2
double rect2_min_x = min(s2.start.x,s2.end.x);
double rect2_max_x = max(s2.start.x,s2.end.x);
double rect2_min_y = min(s2.start.y,s2.end.y);
double rect2_max_y = max(s2.start.y,s2.end.y);
// innerRect of rect1 and rect2
double innerRect_min_x = max(rect1_min_x,rect2_min_x);
double innerRect_max_x = min(rect1_max_x,rect2_max_x);
if(innerRect_min_x > innerRect_max_x)
return false;
double innerRect_min_y = max(rect1_min_y,rect2_min_y);
double innerRect_max_y = min(rect1_max_y,rect2_max_y);
if(innerRect_min_y > innerRect_max_y)
return false;
return true;
}
inline double CrossProduct(const Coordinate& c1,const Coordinate& c2)
{
return c1.x*c2.y-c2.x*c1.y;
}
inline bool isCrossed(const Stick& s1,const Stick& s2)
{
if(!isRectCrossed(s1,s2))
return false;
if(CrossProduct(Coordinate(s1.start.x-s2.start.x,s1.start.y-s2.start.y),Coordinate(s2.end.x-s2.start.x,s2.end.y-s2.start.y))*CrossProduct(Coordinate(s2.end.x-s2.start.x,s2.end.y-s2.start.y),Coordinate(s1.end.x-s2.start.x,s1.end.y-s2.start.y))>=0 &&
CrossProduct(Coordinate(s2.start.x-s1.start.x,s2.start.y-s1.start.y),Coordinate(s1.end.x-s1.start.x,s1.end.y-s1.start.y))*CrossProduct(Coordinate(s1.end.x-s1.start.x,s1.end.y-s1.start.y),Coordinate(s2.end.x-s1.start.x,s2.end.y-s1.start.y))>=0 )
return true;
return false;
}
int main()
{
vector<Stick> vecStick;
vecStick.push_back(Stick()); //Not use the first one.
while(1)
{
int n = 0;
scanf("%d",&n);
if(n == 0)
break;
for(int i =1; i<=n; i++)
{
double x1,y1,x2,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
vecStick.push_back(Stick(i,x1,y1,x2,y2));
}
bool firstFlag = true;
for(int i =1; i<n; i++)
{
bool crossed = false;
for(int j = i+1; j<=n; j++)
{
if(isCrossed(vecStick[i],vecStick[j]))
{
crossed = true;
break;
}
}
if(!crossed)
{
if(firstFlag)
{
printf("Top sticks: %d",i);
firstFlag = false;
}
else
{
printf(", %d",i);
}
}
}
printf(", %d.\n",n);
vecStick.clear();
vecStick.push_back(Stick()); //Not use the first one.
}
return 0;
}
作者:咆哮的马甲
出处:http://www.cnblogs.com/arthurliu/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
转载请保持文档的完整性,严禁用于任何商业用途,否则保留追究法律责任的权利。