poj3348

题意:求凸包面积除以50的值

解法:凸包,向量叉积求面积


#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#define MAXN 50005
#define eps 0.000000000001

struct node{int x,y;double ksc;}g[MAXN]={0},a[MAXN]={0},q1,q2,swap;
double pi;

int n,ans=0;

int stack[MAXN]={0},top=0;

int calc(struct node a,struct node b)
{
    return a.x*b.y-a.y*b.x;
}
void push(int x)
{
    stack[++top]=x;
}
void pop()
{
    stack[top--]=0;
}
int max(int x,int y)
{
    return (x>y)?x:y;
}
int dist(struct node a,struct node b)
{
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int square(struct node a,struct node b,struct node c)
{
    a.x-=c.x,a.y-=c.y;
    b.x-=c.x,b.y-=c.y;

    return abs(calc(a,b));
}

void sort(int a,int b)
{   
    int i=a,j=b;
    struct node t=g[a+rand()%(b-a+1)];

    while(i<=j)
    {
        while(g[i].ksc<t.ksc || (fabs(g[i].ksc-t.ksc)<eps)&&g[i].x<t.x)i++;
        while(g[j].ksc>t.ksc || (fabs(g[j].ksc-t.ksc)<eps)&&g[j].x>t.x)j--;

        if(i<=j)
        {
            swap=g[i];
            g[i]=g[j];
            g[j]=swap;
            i++,j--;
        }
    }

    if(a<j)sort(a,j);
    if(i<b)sort(i,b);
}
int main()
{
    int i,j,p;
    int s1,s2;

    #ifndef ONLINE_JUDGE
    freopen("poj3348.in","r",stdin);
    freopen("poj3348.out","w",stdout);
    #endif

    srand(time(NULL));

    scanf("%d",&n);

    if(n>=3)
    {
    for(i=1;i<=n;i++)
    {
        scanf("%d%d",&g[i].x,&g[i].y);

        if(g[i].x<g[1].x)
          swap=g[i],g[i]=g[1],g[1]=swap;
    }

    pi=acos(-1);

    for(i=2;i<=n;i++)
    {
        g[i].x-=g[1].x,g[i].y-=g[1].y;

        if(g[i].x)
        {
         g[i].ksc=atan((double)g[i].y/g[i].x);
        }
        else
        {
            if(g[i].y>0)     g[i].ksc=pi/2;
            else if(g[i].y<0)g[i].ksc=-pi/2;
            else             g[i].ksc=0;
        }
    }
    g[1].x=g[1].y=0;g[i].ksc=0;

    if(n>2)sort(2,n);

    push(1);push(2);

    for(i=3;i<=n;i++)
    {
        while(top>=2)
        {
          q1.x=g[stack[top]].x-g[stack[top-1]].x;
          q1.y=g[stack[top]].y-g[stack[top-1]].y;

          q2.x=g[i].x-g[stack[top-1]].x;
          q2.y=g[i].y-g[stack[top-1]].y;

          if(calc(q1,q2)<0)
          {
            pop();
          }
          else
            break;
        }

        push(i);
    }

    for(i=1,s1=0;i<top;i++)
    {
         s1+=calc(g[stack[i]],g[stack[i+1]]);
    }
    s1+=calc(g[stack[top]],g[stack[1]]);


    printf("%d",abs(s1)/100);

    }
    else
        printf("0");

    #ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
    #endif
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值