POJ1113

我的第一个凸包。之前我太幼稚了。我通过对Graham-Scan的理解写了一个凸包。但是不知道为什么现在还是WA,我不会极角的排序,于是我写的这个是水平排序,然后分别扫左链和右链。。。但是现在还没有过,看到日志的同学能帮忙看看卡错在哪里么?(代码见后)后来突然想到这样经典的算法应该会有模板的吧,于是找了份模板。但是在G++的环境下,只能%.0f这很是坑人。让我得了好几个WA。今天的多校赛,我敲了一份那个求重心然后二分的那个,但是不知道为什么需要每个点的二分,而不是看到重心不在里面的时候再二分。很是困惑。只是到了最后也没能调出来,其实计算几何的东西要的就是耐心和细心,只是我都没有,所以路漫漫兮。博弈的问题我很是薄弱,几乎都没做过类似的题目,所以今天开始学学博弈。

上代码:(我自己写的Graham-Scan但是WA的代码):

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
struct point {
   int x;
   int y;
};
int Comp(const void *p1,const void *p2)
{
return (*(struct point *)p2).y>(*(struct point *)p1).y? 1 : -1;
}
int dblcmp(double d){
if(fabs(d)<1e-6)
return 0;
else{
if(d>0)
return 1;
else
return -1;
}
}
double det(double x1,double y1,double x2,double y2){
return x1*y2-x2*y1;
}
double cross(struct point a,struct point b,struct point c){
return det(b.x-a.x,b.y-a.y,c.x-b.x,c.y-b.y);
}
main(){
    int n,l,min,max,j,k,i;
    double ans;
    struct point a[1010],b[1010][2],c[1010];
    scanf("%d%d",&n,&l);
    for(i=0;i<=n-1;i++){
        scanf("%d%d",&a[i].x,&a[i].y);
    }
    qsort(a,n,sizeof(a[0]),Comp);
printf("jj\n");
    k=0;
    for(i=0;i<=n-1;i=j+1){
        min=a[i].x;max=a[i].x;
        j=i;
        b[k][0].y=a[i].y;
        b[k][1].y=a[i].y;
    while(a[j].y==a[j+1].y){
        j++;
        if(a[j].x<min)
        min=a[j].x;
        if(a[j].x>max)
        max=a[j].x;
    }
    b[k][0].x=min;
    b[k][1].x=max;
    k++;
    }
    j=2;
    c[0].x=b[k-1][0].x;
    c[0].y=b[k-1][0].y;
    c[1].x=b[k-1][1].x;
    c[1].y=b[k-1][1].y;
     for(i=k-2;i>=0;i--){
     if(dblcmp(cross(c[j-1],c[j],b[i][1]))==1){
     c[++j].x=b[i][1].x;
     c[j].y=b[i][1].y;
     }
     else{
     c[j].x=b[i][1].x;
     c[j].y=b[i][1].y;
     }
     }
    c[++j].x=b[0][0].x;
    c[j].y=b[0][0].y;
    for(i=1;i<=k-1;i++){
    if(dblcmp(cross(c[j-1],c[j],b[i][0]))==1){
         c[++j].x=b[i][0].x;
     c[j].y=b[i][0].y;
    }
    else{
     c[j].x=b[i][0].x;
     c[j].y=b[i][0].y;
     }
    }
    ans=0;
    for(i=0;i<=j-1;i++){
        ans+=sqrt((c[i].x-c[i+1].x)*(c[i].x-c[i+1].x)+(c[i].y-c[i+1].y)*(c[i].y-c[i+1].y));
    }
    ans+=atan(1)*8*l;
    printf("%.0lf\n",ans);
}


用的模板(AC代码):

#include<cstdio>
#include<cmath>
#include <algorithm>
using namespace std;
struct point { double x, y; };
bool mult(point sp, point ep, point op){
return (sp.x - op.x) * (ep.y - op.y)
>= (ep.x - op.x) * (sp.y - op.y);
}
bool operator < (const point &l, const point &r){
return l.y < r.y || (l.y == r.y && l.x < r.x);
}
int graham(point pnt[], int n, point res[]){
int i, len, k = 0, top = 1;
sort(pnt, pnt + n);
if (n == 0) return 0; res[0] = pnt[0];
if (n == 1) return 1; res[1] = pnt[1];
if (n == 2) return 2; res[2] = pnt[2];
for (i = 2; i < n; i++) {
while (top && mult(pnt[i], res[top], res[top-1]))
top--;
res[++top] = pnt[i];
}
len = top; res[++top] = pnt[n - 2];
for (i = n - 3; i >= 0; i--) {
while (top!=len && mult(pnt[i], res[top], res[top-1])) top--;
res[++top] = pnt[i];
}
return top;
}
main(){
int n,l,top,i;
struct point pnt[1010],res[1010];
double ans;
scanf("%d%d",&n,&l); 
for(i=0;i<=n-1;i++){
        scanf("%lf%lf",&pnt[i].x,&pnt[i].y);
    }
    top=graham(pnt,n,res);
    ans=0;
    for(i=0;i<=top-2;i++){
     ans+=sqrt((res[i].x-res[i+1].x)*(res[i].x-res[i+1].x)+(res[i].y-res[i+1].y)*(res[i].y-res[i+1].y));
    }
    ans+=sqrt((res[i].x-res[0].x)*(res[i].x-res[0].x)+(res[i].y-res[0].y)*(res[i].y-res[0].y));
     ans+=2*3.141592653*l;
    printf("%.0f\n",ans);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值