凸包问题

 [Input example]

2

7

10 30 30 10 20 0 30 30 50 10 40 50 60 30

20

8 -2 39 38 -22 -5 0 64 70 -8 -7 -30 40 -21 68 12 30 46 58 45 -24 40 8 1 16 66 41 58 37 25 20 -22 43 38 -12 14 29 40 -9 -4

[Output example]

1500.00

6863.50

#include <stdio.h>
#include <stdlib.h>

typedef struct _SPOT_{
    int x;
    int y;
} Spot;

int N;
Spot data[105];

int stack[105];
int top;
double Answer;

int dis(Spot *a,Spot *b)
{
    return (a->x-b->x)*(a->x-b->x)+(a->y-b->y)*(a->y-b->y);
}

//ac bc
int multiCross(Spot *a,Spot *b,Spot *c)
{
    return (a->x-c->x)*(b->y-c->y)-(b->x-c->x)*(a->y-c->y);
}

int compAngle(const void *a,const void *b)
{
    Spot *sa=(Spot *)a;
    Spot *sb=(Spot *)b;

    int angle=multiCross(sa,sb,&data[1]);

    if(angle<0) return 1;
    else if(angle>0) return -1;
    else {
        if(dis(sa,&data[1])-dis(sb,&data[1])>0) return 1;
        else if(dis(sa,&data[1])-dis(sb,&data[1])<0) return -1;
        else return 0;
    }
}

void grahanScan()
{
    //get minIndex
    int i;
    int minIndex=1;
    for(i=2;i<=N;i++) {
        if((data[minIndex].y>data[i].y)||((data[minIndex].y==data[i].y)&&(data[minIndex].x>data[i].x))) {
            minIndex=i;
        }
    }

    //swap 
    if(minIndex!=1) {
        Spot temp;
        temp=data[minIndex];
        data[minIndex]=data[1];
        data[1]=temp;
    }

    //sort data by angle
    qsort(data+2,N-1,sizeof(data[0]),compAngle);

    //scan convex hull stack
    for(i=1;i<=3;i++) stack[i]=i;
    top=3;

    for(i=4;i<=N;i++) {
        //pop 
        while(multiCross(&data[i],&data[stack[top]],&data[stack[top-1]])>=0) {
            if(top==0) break;
            top--;
        }
        top++;
        stack[top]=i;
    }
}

double convexHullArea()
{
    double sum=0;

    int i;
    for(i=2;i<=top-1;i++){
        sum+=multiCross(&data[stack[i]],&data[stack[i+1]],&data[1]);
    }

    return sum/2;
}

int main(void)
{
    int tc, T, i;

    freopen("sample.txt", "r", stdin);

    setbuf(stdout, NULL);

    scanf("%d", &T);
    for(tc = 0; tc < T; tc++)
    {
        scanf("%d", &N);
        for(i=1;i<=N;i++) {
            scanf("%d %d", &data[i].x,&data[i].y);
        }
        
        //convex hull scan
        grahanScan();

        Answer=convexHullArea();
        
        // Print the answer to standard output(screen).
        printf("%.2f
", Answer);
    }

    return 0;//Your program should return 0 on normal termination.
}
原文地址:https://www.cnblogs.com/mr-redrum/p/3584741.html