poj 1696

贪心+计算几何(叉点积)

个人认为本体用贪心解释最合理,我就是用贪心思考的此题

代码些的太挫啦

#include <iostream>
#include <stdio.h>
#include <stack>
#include <math.h>
#include <string.h> 
using namespace std;
const int maxn=55;
int m,n;
int vis[maxn];
int path[maxn];
struct Point
{
	int x,y;
	Point(int x=0,int y=0):x(x),y(y) { }
};
struct Plant
{
	Point po;
	int ind;
};
struct seg
{
	Point u,v;
};
Plant pla[maxn];
int cross(Point a,Point b,Point c,Point d)
{
   return (b.x-a.x)*(d.y-c.y)-(b.y-a.y)*(d.x-c.x);	
}
int judge(Point a,Point b,Point c,Point d)
{
	int c1=cross(a,b,a,c),c2=cross(a,b,a,d),
		c3=cross(c,d,c,a),c4=cross(c,d,c,b);
	if(c1*c2<0&&c3*c4<0) return 1;
	else return 0;
}
int dot(Point a,Point b,Point c,Point d) { return (b.x-a.x)*(d.x-c.x)+(b.y-a.y)*(d.y-c.y); }
double length(Point a,Point b) { return sqrt(double(dot(a,b,a,b))); }
double Angle(Point a,Point b,Point c)
{
	return acos(dot(a,b,b,c)/length(a,b)/length(b,c));
}
int main()
{
	scanf("%d",&m);
	while(m--)
	{
		scanf("%d",&n);
		int i;
		int miny=1000,minx=1000,start;
		seg s[maxn];
		int top=0;
		for(i=0;i<n;i++)
		{
			scanf("%d%d%d",&pla[i].ind,&pla[i].po.x,&pla[i].po.y);
			if(pla[i].po.y<miny||(pla[i].po.y==miny&&pla[i].po.x<minx))
			{
				miny=pla[i].po.y;
				minx=pla[i].po.x;
				start=i;
			}
		}
		memset(vis,0,sizeof(vis));
		int next=start;
		int	tot=0;
		path[tot++]=start;
		Point pre=Point(0,pla[start].po.y);
		s[top].u=pre;s[top++].v=pla[start].po;
		int tem;
		for(;;)
		{
			tem=next;
			vis[tem]=1;
			double ang=acos(-1);
			for(i=0;i<n;i++)
			{
				if(vis[i]) continue;
				if(cross(pre,pla[tem].po,pla[tem].po,pla[i].po))
				{
					int j;
					for(j=0;j<top;j++)
					{
						if(judge(s[j].u,s[j].v,pla[i].po,pla[tem].po)) break;
					}
					if(j==top)
					{
						double ta=Angle(pre,pla[tem].po,pla[i].po);
						if(ta-ang<-1e-10)
						{
							ang=ta;
							next=i;
						}
						else if(ta==ang) 
						{
							if(length(pla[tem].po,pla[i].po)<length(pla[tem].po,pla[next].po))
								next=i;
						}
					}
				}
			}
			if(next==tem) break;
			else
			{
				path[tot++]=next;
				pre=pla[tem].po;
				s[top].u=pla[tem].po;
				s[top++].v=pla[next].po;
			}
		}
		printf("%d ",tot);
		for(i=0;i<tot-1;i++) printf("%d ",path[i]+1);
		printf("%d\n",path[i]+1);
	}
	return 0;
}


 

原文地址:https://www.cnblogs.com/lj030/p/3002336.html