您的位置:首页 > 其它

cogs896 圈奶牛

2016-06-09 18:25 260 查看

 

描述

农夫约翰想要建造一个围栏用来围住他的奶牛,可是他资金匮乏。他建造的围栏必须包括他的奶牛喜欢吃草的所有地点。对于给出的这些地点的坐标,计算最短的能够围住这些点的围栏的长度。

PROGRAM NAME: fc

INPUT FORMAT(file fc.in)

输入数据的第一行包括一个整数 N。N(0 <= N <= 10,000)表示农夫约翰想要围住的放牧点的数目。接下来 N 行,每行由两个实数组成,Xi 和 Yi,对应平面上的放牧点坐标(-1,000,000 <= Xi,Yi <= 1,000,000)。数字用小数表示。

OUTPUT FORMAT(file fc.out)

输出必须包括一个实数,表示必须的围栏的长度。答案保留两位小数。

SAMPLE INPUT (file fc.in)

4
4 8
4 12
5 9.3
7 8

SAMPLE OUTPUT (file fc.out)

12.00



graham凸包算法
注意读进来的有小数
/*by SilverN*/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int mxn=20000;
struct node{
double x,y;
}p[mxn],s[mxn];
int top;
double ans;
int n;
inline node operator -(node a,node b){
node T;    T.x=a.x-b.x;    T.y=a.y-b.y;    return T;
}
inline double operator *(node a,node b){
return a.x*b.y-a.y*b.x;
}
inline double dis(node a,node b){
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
inline bool operator < (node a,node b){
ll t=(a-p[1])*(b-p[1]);
if(t==0)return dis(a,p[1])<dis(b,p[1]);
return t>0;
}
void graham(){
int i,j;
int t=1;
for(i=2;i<=n;i++){
if(p[i].y<p[t].y || (p[i].y==p[t].y && p[i].x<p[t].x))t=i;
}
swap(p[1],p[t]);
sort(p+2,p+n+1);
s[1]=p[1];
s[2]=p[2];top=2;
for(i=3;i<=n;i++){
while(top && ((s[top]-s[top-1])*(p[i]-s[top-1]))<0 )top--;
s[++top]=p[i];
}
s[top+1]=p[1];
for(i=1;i<=top;i++){
ans+=sqrt(dis(s[i],s[i+1]));
}
return;
}
int main(){
//    freopen("fc.in","r",stdin);
//    freopen("fc.out","w",stdout);
scanf("%d",&n);
int i,j;
for(i=1;i<=n;i++){
scanf("%lf%lf",&p[i].x,&p[i].y);
}
graham();
printf("%.2lf\n",ans);
return 0;
}

 

Andrew凸包

/*by SilverN*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
const int mxn=100010;
struct point{
double x,y;
point operator + (const point &b){return (point){x+b.x,y+b.y};}
point operator - (const point &b){return (point){x-b.x,y-b.y};}
point operator * (const double v){return (point){x*v,y*v};}
bool operator < (const point &b)const{
return x<b.x || (x==b.x && y<b.y);
}
}a[mxn];
double dot(const point &a,const point &b){return a.x*b.x,a.y*b.y;}
double Cross(const point &a,const point &b){return a.x*b.y-a.y*b.x;}
double dist(const point &a,const point &b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int n;
int st[mxn],top,t2;
void andrew(){
a[n+1]=a[1];
top=t2=0;
for(int i=1;i<=n;i++){
while(top>1 && Cross(a[i]-a[st[top-1]],a[st[top]]-a[st[top-1]])>=0)top--;
st[++top]=i;
}
t2=top;
for(int i=n-1;i;i--){
while(t2>top && Cross(a[i]-a[st[t2-1]],a[st[t2]]-a[st[t2-1]])>=0)t2--;
st[++t2]=i;
}
return;
}
int main(){
//    freopen("fc.in","r",stdin);
//    freopen("fc.out","w",stdout);
int i,j;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%lf%lf",&a[i].x,&a[i].y);
sort(a+1,a+n+1);
andrew();
//    for(i=1;i<=t2;i++)
//        printf("%.3f %.3f\n",a[st[i]].x,a[st[i]].y);
double ans=0;
for(i=1;i<t2;i++)
ans+=dist(a[st[i]],a[st[i+1]]);
printf("%.2f\n",ans);
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: