POJ 1696 Space Ant (向量的叉积)

来源:互联网 发布:淘宝韩国代购真假 编辑:程序博客网 时间:2024/05/18 01:28

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

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

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

判断点用的就是叉积了

//Memory: 260K//Time: 0MS#include <iostream>#include <string.h>#include <math.h>#include <algorithm>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<<n;for(i=1;i<=n;i++)cout<<" "<<ch[i].num;cout<<endl;}return 0;}

原创粉丝点击