zoukankan      html  css  js  c++  java
  • CodeForces

    A point belongs to a triangle if it lies inside the triangle or on one of its sides. Two triangles are disjoint if there is no point on the plane that belongs to both triangles.

    You are given nn points on the plane. No two points coincide and no three points are collinear.

    Find the number of different ways to choose two disjoint triangles with vertices in the given points. Two ways which differ only in order of triangles or in order of vertices inside triangles are considered equal.

    Input

    The first line of the input contains an integer nn (6n20006≤n≤2000) – the number of points.

    Each of the next nn lines contains two integers xixi and yiyi (|xi|,|yi|109|xi|,|yi|≤109) – the coordinates of a point.

    No two points coincide and no three points are collinear.

    Output

    Print one integer – the number of ways to choose two disjoint triangles.

    Examples

    Input
    6
    1 1
    2 2
    4 6
    4 5
    7 2
    5 3
    Output
    6
    Input
    7
    0 -1000000000
    -5 -5
    5 -5
    -5 0
    5 0
    -2 2
    2 2
    Output
    21

    题意:现在有N个点,满足没有三点共线,问有对少对三角形,满足没有公共部分。

    思路:如果两个三角形A,B不相交,则有两种方式满足:A选择一个点a,B选择一个点b,三角形AB被直线ab隔开。那么我们枚举直线,然后直线两侧的点数分别是x,y,则其贡献是C(x,2)*C(y,2)*2,*2是因为有a可以和x部分组合,也可以和y部分组合,但最后要/2,因为没对三角形有两种直线满足。

    具体的,我们用到了atan2(y1-y2,x1-x2),在一二象限为正,三四象限为负。

    #include<bits/stdc++.h>
    #define ll long long
    #define pii pair<int,int>
    #define pdd pair<double,double>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define F first
    #define S second
    using namespace std;
    const double pi=acos(-1.0);
    const int maxn=2010;
    pdd a[maxn]; double w[maxn];
    int main()
    {
        int N; ll ans=0;
        scanf("%d",&N);
        rep(i,1,N) scanf("%lf%lf",&a[i].F,&a[i].S);
        rep(i,1,N){
            int tot=0;
            rep(j,1,N) if(j!=i) w[++tot]=atan2(a[j].S-a[i].S,a[j].F-a[i].F); //纵坐标在前,横在后 
            sort(w+1,w+1+tot);
            for(int j=1,k=1;j<=tot&&w[j]<=0;j++){
                while(k<=tot&&w[k]-w[j]<pi) k++;
                ans+=(ll)(k-j-1)*(k-j-2)/2*(tot-k+j)*(tot-k+j-1)/2;
            }
        }
        printf("%I64d
    ",ans);
        return 0;
    }
  • 相关阅读:
    android界面横屏和竖屏的切换
    google 提供webrtc 的实例使用 turnserver的方式
    如何使官方提供的AppRTCDemo 运行在自己搭建的server(官方提供的apprtc)上(官方的server源码)
    android在全屏下第一次触摸屏幕没有触发事件
    ubuntu常用命令记录集
    python 一个包中的文件调用另外一个包文件 实例
    python-插入排序
    phantomjs submit click
    python socket.error: [Errno 10054] 解决方法
    python-快速排序,两种方法→易理解
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9539128.html
Copyright © 2011-2022 走看看