两个while循环求凸包 poj2187 poj1113

两个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.&& 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.) 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.&& 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);

    }   
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值