我的第一个凸包。之前我太幼稚了。我通过对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);
}