学习过斜率优化的童鞋们应该对凸包都不陌生,这里就不做详细的介绍了
手动上代码 P2742 【模板】二维凸包
#include
#include
#include
#include
using namespace std;
const int N=100010;
const double eps=1e-8;
struct vector {
double x,y;
vector(double x=0,double y=0):x(x),y(y) {};
};
#define point vector
vector operator + (vector a,vector b) {return vector(a.x+b.x,a.y+b.y);}
vector operator - (vector a,vector b) {return vector(a.x-b.x,a.y-b.y);}
vector operator * (vector a,double k) {return vector(a.x*k,a.y* k);}
vector operator / (vector a,double k) {return vector(a.x/k,a.y/k);}
double operator * (vector a,vector b) {return a.x*b.x+a.y*b.y;}
double operator ^ (vector a,vector b) {return a.x*b.y-b.x*a.y;}
vector d[N],hull[N];
bool operator < (point a,point b) {return a.x==b.x?a.y<b.y:a.x<b.x;}
int n,m;
double len(vector a) {return sqrt(a.x*a.x+a.y*a.y);}
void get_hull() {
m=2;
hull[1]=d[1],hull[2]=d[2];
for(int i= 3;i<=n;++i) {
while(m>1&&(((hull[m]-hull[m-1])^(d[i]-hull[m-1]))-eps<0)) --m;
hull[++m]=d[i];
}
int k=m;
for(int i=n-1;i>=1;--i) {
while(m>k&&(((hull[m]-hull[m-1])^(d[i]-hull[m-1]))-eps<0)) --m;
hull[++m]=d[i];
}
}
int main() {
cin>>n;
for(int i=1; i<=n; ++i)
cin>>d[i].x>>d[i].y;
sort(d+1,d+n+1) ;
get_hull();
double ans;
for(int i=1;i<m;++i )
ans+=len(hull[i]-hull[i+1]);
printf("%.2lf\n",ans);
return 0;
}
还有一个板子题poj1113 Wall
#include
#include
#include
#include
using namespace std;
const int N=100010;
const double eps=1e-8,pi=acos(-1.0);
struct vector {
double x,y;
vector(double x=0,double y=0):x(x),y(y) {};
};
#define point vector
vector operator + (vector a,vector b) {return vector(a.x+b.x,a.y+b.y);}
vector operator - (vector a,vector b) {return vector(a.x-b.x,a.y-b.y);}
vector operator * (vector a,double k) {return vector(a.x*k,a.y* k);}
vector operator / (vector a,double k) {return vector(a.x/k,a.y/k);}
double operator * (vector a,vector b) {return a.x*b.x+a.y*b.y;}
double operator ^ (vector a,vector b) {return a.x*b.y-b.x*a.y;}
vector d[N],hull[N];
bool operator < (point a,point b) {return a.x==b.x?a.y<b.y:a.x<b.x;}
double l ;
int n,m;
double len(vector a) {return sqrt(a.x*a.x+a.y*a.y);}
void get_hull() {
m=2;
hull[1]=d[1],hull[2]=d[2];
for(int i= 3;i<=n;++i) {
while(m>1&&(((hull[m]-hull[m-1])^(d[i]-hull[m-1]))-eps<0)) --m;
hull[++m]=d[i];
}
int k=m;
for(int i=n-1;i>=1;--i) {
while(m>k&&(((hull[m]-hull[m-1])^(d[i]-hull[m-1]))-eps<0)) --m;
hull[++m]=d[i];
}
}
int main() {
cin>>n>>l;
for(int i=1; i<=n; ++i)
cin>>d[i].x>>d[i].y;
sort(d+1,d+n+1) ;
get_hull();
double ans=0;
hull[m+1]=hull[1];
for(int i=1;i<=m;++i )
ans+=len(hull[i]-hull[i+1]);
cout<<(int)(ans+2*pi*l+0.5)<<endl;
return 0;
}
同样,凸包也可以用来求平面内最远点对(装作不会旋转卡壳)
P1452 Beauty Contest
#include
#include
#include
#include
using namespace std;
const int N=100010;
const double eps=1e-8;
struct vector {
double x,y;
vector(double x=0,double y=0):x(x),y(y) {};
};
#define point vector
vector operator + (vector a,vector b) {return vector(a.x+b.x,a.y+b.y);}
vector operator - (vector a,vector b) {return vector(a.x-b.x,a.y-b.y);}
vector operator * (vector a,double k) {return vector(a.x*k,a.y* k);}
vector operator / (vector a,double k) {return vector(a.x/k,a.y/k);}
double operator * (vector a,vector b) {return a.x*b.x+a.y*b.y;}
double operator ^ (vector a,vector b) {return a.x*b.y-b.x*a.y;}
vector d[N],hull[N];
bool operator < (point a,point b) {return a.x==b.x?a.y<b.y:a.x<b.x;}
int n,m;
double len(vector a) {return (a.x*a.x+a.y*a.y);}
void get_hull() {
m=2;
hull[1]=d[1],hull[2]=d[2];
for(int i= 3;i<=n;++i) {
while(m>1&&(((hull[m]-hull[m-1])^(d[i]-hull[m-1]))-eps<0)) --m;
hull[++m]=d[i];
}
int k=m;
for(int i=n-1;i>=1;--i) {
while(m>k&&(((hull[m]-hull[m-1])^(d[i]-hull[m-1]))-eps<0)) --m;
hull[++m]=d[i];
}
}
int main() {
cin>>n;
for(int i=1; i<=n; ++i)
cin>>d[i].x>>d[i].y;
sort(d+1,d+n+1) ;
get_hull();
double ans=0;、
for(int i=1;i<m;++i )
for(int j=1;j<=m;++j)
ans=max(len(hull[i]-hull[j]),ans);
cout<<(int)ans<<endl ;
return 0;
}
poj 1228 Grandpa’s Estate
题意:意思就是给你一堆点,这堆点本来就是某个凸包上的部分点,问你这堆点是否能确定唯一的凸包
这个题目的题本蒟蒻看了很久很久没有看懂,后来求助某巨佬学习到了什么叫做稳定凸包
还有一个简单题poj3348Cows
这个题目就是求凸包,然后运用叉积求面积,然后看整除多少个五十即可
#include
#include
#include
#include
using namespace std;
const int N=100010;
const double eps=1e-8;
struct vector {
double x,y;
vector(double x=0,double y=0):x(x),y(y) {};
};
#define point vector
vector operator + (vector a,vector b) {return vector(a.x+b.x,a.y+b.y);}
vector operator - (vector a,vector b) {return vector(a.x-b.x,a.y-b.y);}
vector operator * (vector a,double k) {return vector(a.x*k,a.y* k);}
vector operator / (vector a,double k) {return vector(a.x/k,a.y/k);}
double operator * (vector a,vector b) {return a.x*b.x+a.y*b.y;}
double operator ^ (vector a,vector b) {return a.x*b.y-b.x*a.y;}
vector d[N],hull[N];
bool operator < (point a,point b) {return a.x==b.x?a.y<b.y:a.x<b.x;}
int n,m;
double len(vector a) {return sqrt(a.x*a.x+a.y*a.y);}
void get_hull() {
m=2;
hull[1]=d[1],hull[2]=d[2];
for(int i= 3;i<=n;++i) {
while(m>1&&(((hull[m]-hull[m-1])^(d[i]-hull[m-1]))-eps<0)) --m;
hull[++m]=d[i];
}
int k=m;
for(int i=n-1;i>=1;--i) {
while(m>k&&(((hull[m]-hull[m-1])^(d[i]-hull[m-1]))-eps<0)) --m;
hull[++m]=d[i];
}
}
int main() {
cin>>n;
for(int i=1; i<=n; ++i)
cin>>d[i].x>>d[i].y;
sort(d+1,d+n+1) ;
get_hull();
double ans;
hull[m+1]=hull[1];
for(int i=1;i<=m;++i )
ans+=fabs(hull[i]^hull[i+1]);
ans/=2;
cout<<(int)(ans/50)<<endl ;
return 0;
}