• trokuti 三角形


    问题描述
    平面上有N条直线,用方程Aix + Biy +Ci =0表示。这些直线没有三线共点的。现在要你计算出用这些直线可以构造出多少三角形?

    输入格式
    第1行:一个整数N(1 ≤ N≤ 300000)。
    下面N行:每行3个整数:Ai, Bi 和Ci,表示对应直线方程的系数。不超过10^9。

    输出格式
    一行,一个整数。

    数据规模与约定
    对于40%的数据,N ≤1000;
    对于100%的数据,N≤300000。

    ···································································································································································································································································
    注意没有三线共点的。
    如果没有平行线,我们直接求Cn3就行了。
    但是确实有平行线。
    那么……
    我们只要减去多余的就可以了。
    怎样求多余的呢?
    多余的是由我们把平行线算到一个三角形中产生的。
    对于每一种斜率k,它产生的多余的个数是一个三角形中三条线全是这种斜率,或者有两条是这种斜率。
    那么每种斜率产生的多余的个数是Cm3+Cm2*(n-m),m是这种斜率的直线条数。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<cstdio>
    #include<map>
    #define LL long long
    #define N 300009
    using namespace std;
    int n,cnt;
    map <double,int> ma;
    LL num0;//记斜率不存在的线的个数 
    LL C[N];
    LL ans,more[N],s[N]; 
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            double a,b,c;
            scanf("%lf%lf%lf",&a,&b,&c);
            if(b==0) {num0++;continue;}
            double k=-a/b;
            if(ma[k]==0) {ma[k]=++cnt;C[cnt]=1;}
            else C[ma[k]]++;
        }
        if(num0) C[++cnt]=num0;
        ans=1ll*(n-2)*(n-1)*n/6;
    
        for(int i=cnt;i>=1;i--)
        {
            LL t=1ll*C[i]*(C[i]-1)*(C[i]-2)/6+1ll*(C[i]-1)*C[i]/2*(n-C[i]);
            more[i]=t;
        }
        for(int i=1;i<=cnt;i++) ans-=more[i];
        printf("%lld",ans);
        return 0;
    }

    还有一种更巧妙地做法
    组成三角形的三条直线的斜率肯定是k1 < k2 < k3
    我们只要按照枚举k2就可以啦。
    加上k1的个数 * k3的个数*k2的个数

    #include<iostream>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<queue>
    #define N 300009
    #define LL long long
    using namespace std;
    int n,cnt[N],r,s[N];
    double K[N];
    LL ans;
    int main()
    {
        freopen("trokuti.in","r",stdin);
        freopen("trokuti.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            double a,b,c;
            scanf("%lf%lf%lf",&a,&b,&c);
            K[i]=-a/b;
        }
        sort(K+1,K+n+1);
    
        int num=1;
        for(int i=2;i<=n;i++)
        {
            if(K[i]==K[i-1]) num++;
            else 
            {
                cnt[++r]=num;
                num=1;
            }   
        }
        cnt[++r]=num;
        for(int i=1;i<=r;i++) s[i]+=s[i-1]+cnt[i];
    
        for(int i=1;i<=r;i++)
        {
            ans+=1ll*s[i-1]*1ll*(s[r]-s[i])*1ll*cnt[i];
        }
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    [C语言]变长函数参数和变长参数宏
    [转载]腾讯机智团队分享--AllReduce算法的前世今生
    (三)opencv_py之阈值处理
    (二)opencv_py之彩色空间转换
    neo4j 一些常用的CQL
    Neo4j (1)创建节点
    tensorflow实现siamese网络 (附代码)
    早停!? earlystopping for keras
    关于 ESIM 网络的 资料 集合
    聊天机器人资源合集:项目,语聊,论文,教程
  • 原文地址:https://www.cnblogs.com/dfsac/p/7587807.html
Copyright © 2020-2023  润新知