zoukankan      html  css  js  c++  java
  • CF1284E New Year and Castle Construction

    CF1284E New Year and Castle Construction

    传送门

    CodeForces

    题解

    妙啊.

    首先考虑从集合中选出(5)个点出来,把它称为( ext{5-set})

    • ( ext{5-set})的凸包是一个五边形,数量为(x_5).
    • ( ext{5-set})的凸包是一个四边形,数量为(x_4).
    • ( ext{5-set})的凸包是一个三角形,数量为(x_3).

    那么答案就是(x_4+2x_3),考虑每一种的贡献即可.

    这时考虑怎么求这个东西?设(X=x_5+x_4+x_3=inom{n}{5}),(Y=5 imes x_5+4 imes x_4+3 imes x_3),有:(ans=5X-Y).

    所以只需想怎么计算(Y),不难发现(Y)就是每一条边作为凸包中的边的总数,这个东西直接枚举边然后极角排序即可.

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2510;
    struct node{int x,y;}p[N],ret[N<<2];
    int n;
    long long cross(node a,node b){return 1ll*a.x*b.y-1ll*a.y*b.x;}
    bool cmp(node a,node b)
    {
        int flag1=a.y<0||(a.x>0&&!a.y);
    	int flag2=b.y<0||(b.x>0&&!b.y);
        return flag1==flag2?cross(a,b)>0:flag1<flag2;
    }
    long long X,Y;
    long long C5(int n){return 1ll*n*(n-1)/2*(n-2)/3*(n-3)/4*(n-4)/5;}
    long long C3(int n){return 1ll*n*(n-1)/2*(n-2)/3;}
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d%d",&p[i].x,&p[i].y);
        X=C5(n);
        for(int i=1;i<=n;i++)
        {
            int tot=0;
            for(int j=1;j<=n;j++)
                if(i!=j)ret[++tot]=(node){p[j].x-p[i].x,p[j].y-p[i].y};
            sort(ret+1,ret+tot+1,cmp);
            for(int j=1;j<=tot;j++)ret[j+tot]=ret[j];
            int pos=1;
            for(int j=tot+1;j<=tot<<1;j++)
            {
                while(pos+tot-1<j||cross(ret[j],ret[pos])>0)pos++;
                Y+=C3(j-pos);
            }
        }
        printf("%lld
    ",5*X-Y);
        return 0;
    }
    
  • 相关阅读:
    java作用域public ,private ,protected 及不写时的区别
    JAVA的静态变量、静态方法、静态类
    栈内存 堆内存
    java
    数组 bash shell
    SYN Cookie的原理和实现
    Python 时间 time
    sysctl命令详解
    lvs
    软件工程概论个人作业01
  • 原文地址:https://www.cnblogs.com/fexuile/p/12875468.html
Copyright © 2011-2022 走看看