POJ 1696 Space Ant (向量的叉积)

一只很特殊的蚂蚁,只能向坐转,并且不能经过已经走过的路。一张地图上有n个食物让蚂蚁去采集,求蚂蚁经过食物的顺序。

一开始想偷懒,直接甩graham凸包模版上去,加了一条判断和搜索点的重排。。果断WA

好吧果然还是不能偷懒啊!每确定一个点以它为起点找逆时针一个个碰到的点。。其实大概或许就是卷包裹求凸包了吧。。不太了解的说。。

判断点用的就是叉积了

//Memory: 260K		
//Time: 0MS
#include 
#include 
#include 
#include 
using namespace std;
bool use[100];
struct POINT
{
	double x,y;
	int num;
};POINT PointSet[100],ch[100];
double dist(POINT p1,POINT p2)              
{ 
	return( sqrt( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) ) ); 
}
/******************************************************************************\
	r=multiply(sp,ep,op),得到(sp-op)和(ep-op)的叉积 
	r>0:ep在矢量opsp的逆时针方向; 
	r=0:opspep三点共线; 
	r<0:ep在矢量opsp的顺时针方向 
\******************************************************************************/ 
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)); 
}
void getans(int n) 
{ 
	int i,k=0,sum=1,minp=50,p=0;
	bool flag;
	while(sum<=n)
	{
		minp=100000;
		flag=true;
		for(i=1;i<=n;i++)
		{
			if(!use[ PointSet[i].num ])
			{	
				if(flag)
				{	minp=i;
					flag=false;
				}
				else
				{
					if(multiply(PointSet[minp],PointSet[i],PointSet[p])<0||		// 极角更小  
						(multiply(PointSet[minp],PointSet[i],PointSet[p])==0) &&	/* 极角相等,距离更短 */        
						dist(PointSet[p],PointSet[minp])>dist(PointSet[p],PointSet[i]))
					minp=i;
				}
			}
		}
		ch[sum++]=PointSet[minp];
		use[ PointSet[minp].num ]=true;
		p=minp;
	}
}
int main()
{
	int n,cas,i;
	cin>>cas;
	while(cas--)
	{
		cin>>n;
		memset(use,0,sizeof(use));
		double miny=1000000;
		for(i=1;i<=n;i++)
		{
			cin>>PointSet[i].num>>PointSet[i].x>>PointSet[i].y;
			miny=min(miny,PointSet[i].y);
		}
		PointSet[0].x=0;PointSet[0].y=miny;
		getans(n);
		cout<

你可能感兴趣的:(POJ,计算几何)