两个while循环求凸包
//poj 2187
#include<algorithm>
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
using namespace std;
const double EP =1E-10;
struct POINT
{
int x; int y;
POINT(int a=0, int b=0) { x=a; y=b;} //constructor
};
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));
}
int dist_2(POINT p1,POINT p2) // 返回两点之间欧氏距离的平方
{
return( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) );
}
bool cm(const POINT &a,const POINT &b)
{
if( a.y<b.y||(a.y==b.y && a.x<b.x))
return true;
return false;
}
void Graham_scan(POINT PointSet[],POINT ch[],int n,int &len)
{
sort(PointSet, PointSet+n,cm);
ch[0]=PointSet[0];
ch[1]=PointSet[1];
int top=1;
for(int i=2;i<n;i++)
{
while(top>0&&multiply(ch[top],PointSet[i],ch[top-1])<=0)
{
top--;
}
ch[++top]=PointSet[i];
}
int tmp=top;
for(int i=n-2;i>=0;i--)
{
while(top>tmp&&multiply(ch[top],PointSet[i],ch[top-1])<=0)
top--;
ch[++top]=PointSet[i];
}
len=top;
}
int max(int a,int b)
{
if(a>b)return a;
else return b;
}
int rotating_calipers(POINT ch[],int chsz)
{
int pos=1,ans=0;
ch[chsz]=ch[0];
for(int i=0;i<chsz;i++)
{
while(multiply(ch[i+1],ch[pos],ch[i])<multiply(ch[i+1],ch[pos+1],ch[i]))
pos=(pos+1)%chsz;
ans=max(ans,max(dist_2(ch[i],ch[pos]),dist_2(ch[i+1],ch[pos+1])));
}
return ans;
}//*/
int main()
{
POINT ch[50005];POINT PointSet[50005];
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d%d",&PointSet[i].x,&PointSet[i].y);
}
if(n==2)
{
printf("%d\n",dist_2(PointSet[1],PointSet[0]));
}
else
{
int len;
Graham_scan(PointSet,ch,n,len);
printf("%d\n",rotating_calipers(ch,len));
}
}
}
//*****************
poj 1113
#include<algorithm>
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
using namespace std;
const double EP =1E-10;
const double PI =acos(-1.0);
struct POINT
{
double x, y;
POINT(int a=0, int b=0) { x=a; y=b;} //constructor
};
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));
}
struct LINESEG
{
POINT s;
POINT e;
LINESEG(POINT a, POINT b) { s=a; e=b;}
LINESEG() { }
};
inline int pd(LINESEG a)// 如果判断某条线段是否为点。 如果是点返回 1 是线段返回 0
{
if( a.s.x==a.e.x && a.s.y==a.e.y ) return 1;
else return 0;
}
double dist(POINT p1,POINT p2) // 返回两点之间欧氏距离
{
return( sqrt( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) ) );
}
double dotmultiply(POINT p1,POINT p2,POINT p0)
{
return ((p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y));
}
double relation(POINT p,LINESEG l)
{
LINESEG tl;
tl.s=l.s;
tl.e=p;
return dotmultiply(tl.e,l.e,l.s)/(dist(l.s,l.e)*dist(l.s,l.e));
}
POINT perpendicular(POINT p,LINESEG l)
{
double r=relation(p,l);
POINT tp;
tp.x=l.s.x+r*(l.e.x-l.s.x);
tp.y=l.s.y+r*(l.e.y-l.s.y);
return tp;
}
double ptolinesegdist(POINT p,LINESEG l,POINT &np)
{
double r=relation(p,l);
if(r<0)
{
np=l.s;
return dist(p,l.s);
}
if(r>1)
{
np=l.e;
return dist(p,l.e);
}
np=perpendicular(p,l);
return dist(p,np);
}
bool intersect(LINESEG u,LINESEG v)
{
return( (max(u.s.x,u.e.x)>=min(v.s.x,v.e.x))&& //排斥实验
(max(v.s.x,v.e.x)>=min(u.s.x,u.e.x))&& // v中最右的点是否在u最左的点的右边
//判断这两条线段在水平层面上是否可能相交
(max(u.s.y,u.e.y)>=min(v.s.y,v.e.y))&& //u中最上的点是否在v最下的点的上边
(max(v.s.y,v.e.y)>=min(u.s.y,u.e.y))&& //v中最上的点是否在u最下的点的上边
(multiply(v.s,u.e,u.s)*multiply(u.e,v.e,u.s)>=EP)&& //跨立实验
(multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=EP));
//判断u.s,u.e是否分布在v.s两侧(或线上)
}
double dis_linetoline(LINESEG a,LINESEG b)
{
POINT p1=a.s;POINT p2=b.s;
if(pd(a)&&pd(b)) return dist(p1,p2);
if(pd(a)) return ptolinesegdist(p1,b,p2);
if(pd(b)) return ptolinesegdist(p2,a,p1);
//以上是判断两直线是否为点
if(intersect(a,b)) return 0;//判断两直线是否相交,相交返回距离为0
POINT g;
double d1=min(ptolinesegdist(a.s,b,g),ptolinesegdist(a.e,b,g));
double d2=min(ptolinesegdist(b.s,a,g),ptolinesegdist(b.e,a,g));
return min(d1,d2);
}
bool cm(const POINT &a,const POINT &b)
{
if( a.y<b.y||(a.y==b.y && a.x<b.x))
return true;
return false;
}
void Graham_scan(POINT PointSet[],POINT ch[],int n,int &len)
{
sort(PointSet, PointSet+n,cm);
ch[0]=PointSet[0];
ch[1]=PointSet[1];
int top=1;
for(int i=2;i<n;i++)
{
while(top>0&&multiply(ch[top],PointSet[i],ch[top-1])<=0)
{
top--;
}
ch[++top]=PointSet[i];
}
int tmp=top;
for(int i=n-2;i>=0;i--)
{
while(top>tmp&&multiply(ch[top],PointSet[i],ch[top-1])<=0)
top--;
ch[++top]=PointSet[i];
}
len=top;
}
//*/
inline int _4she5ru(double ru)// int _4she5ru(double sum)
{
int d;
if(ceil(ru)-ru<ru-floor(ru))
d=int(ceil(ru));
else d=int(floor(ru));
return d;
}
int main()
{
POINT ch[50005];POINT PointSet[50005];
int n,m,len;
while(scanf("%d %d",&n,&m)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%lf%lf",&PointSet[i].x,&PointSet[i].y);
}
Graham_scan(PointSet,ch,n,len);
//for()
ch[len]=ch[0];
double sum=0;
for(int i=0;i<len;i++)
{
sum+=dist(ch[i],ch[i+1]);
}
//cout<<sum<<endl;
sum+=2*m*PI;
int d=_4she5ru(sum);
printf("%d\n",d);
}
}