计算几何模板(凸包)
模板
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 10005
struct Point
{
double x;
double y;
}point[N];
Point stack[N];
double dis(Point a,Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double cross(Point a,Point b,Point c)
{
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
bool cmp1(Point a,Point b)
{
if(a.y!=b.y)
return a.y<b.y;
else
return a.x<b.x;
}
bool cmp2(Point a,Point b)
{
double res=cross(point[1],a,b);
if(res>0)
return true;
else if(res==0&&dis(point[1],a)<=dis(point[1],b))
return true;
else
return false;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&point[i].x,&point[i].y);
if(n==0||n==1)
printf("0.00\n");
else if(n==2)
printf("%.2lf\n",dis(point[1],point[2]));
else
{
sort(point+1,point+1+n,cmp1);
stack[1]=point[1];
sort(point+1+1,point+1+n,cmp2);
stack[2]=point[2];
int cnt=2;
for(int i=3;i<=n;i++)
{
while(cross(stack[cnt-1],stack[cnt],point[i])<0)
cnt--;
stack[++cnt]=point[i];
}
double ans=0;
for(int i=2;i<=cnt;i++)
ans+=dis(stack[i-1],stack[i]);
ans+=dis(stack[cnt],stack[1]);
printf("%.2lf\n",ans);
}
return 0;
}
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 10005
struct Point
{
double x;
double y;
}point[N];
Point stack[N];
double dis(Point a,Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double cross(Point a,Point b,Point c)
{
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
bool cmp1(Point a,Point b)
{
if(a.y!=b.y)
return a.y<b.y;
else
return a.x<b.x;
}
bool cmp2(Point a,Point b)
{
double res=cross(point[1],a,b);
if(res>0)
return true;
else if(res==0&&dis(point[1],a)<=dis(point[1],b))
return true;
else
return false;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&point[i].x,&point[i].y);
if(n==0||n==1)
printf("0.00\n");
else if(n==2)
printf("%.2lf\n",dis(point[1],point[2]));
else
{
sort(point+1,point+1+n,cmp1);
stack[1]=point[1];
sort(point+1+1,point+1+n,cmp2);
stack[2]=point[2];
int cnt=2;
for(int i=3;i<=n;i++)
{
while(cross(stack[cnt-1],stack[cnt],point[i])<0)
cnt--;
stack[++cnt]=point[i];
}
double ans=0;
for(int i=2;i<=cnt;i++)
ans+=dis(stack[i-1],stack[i]);
ans+=dis(stack[cnt],stack[1]);
printf("%.2lf\n",ans);
}
return 0;
}
板子题……顺便说下这种求凸包的算法叫做Graham扫描法。