【数论】SSL_1143 三角形

本文介绍了一种通过计算几何的方法来找出给定点集中能够构成三角形的所有组合。通过枚举每个点并计算剩余点与该点组成的斜率,排除共线点,最终得出有效三角形的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意

给出NN个点的坐标,求出其中能组成几个三角形。

思路

一个三角形需要三个点组成,所以可以N个点可以组成C3NCN3个三角形,但是可能有三个点在同一条线上,这就不能组成一个三角形。
我们可以换种做法:
枚举一个点,还需要22个点才能和这个点组成三角形。这种方案有C2个。
判断重复的情况,我们求出这些点和枚举的点的斜率,判断是不是在同一条线上,然后减去相应的方案数。
还要判断斜率不存在的情况,误差不超过1e-9。

代码

#include<cstdio>
#include<algorithm>

const double eps = 1e-9;
int n;
long long ans;
int x[3001], y[3001];
double p[3001];

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d %d", &x[i], &y[i]);
    for (int i = 3; i <= n; i++) {
        ans += (i - 1) * (i - 2) / 2;
        int t = 0;//t存斜率不存在的边个数
        for (int j = 1; j < i; j++) {
            if (!(x[i] - x[j])) t++;
            p[j] = (double)(y[i] - y[j]) / (x[i] - x[j]);
        }
        std::sort(p + 1, p + i);
        p[i] = 2147483647;
        int k = 1;
        for (int j = 2; j <= i; j++) {
            if (p[j] - p[j - 1] <= eps) k++;
            else {
                ans -= k * (k - 1) / 2;//减去相同斜率情况
                k = 1;
            }
        }
        ans -= t * (t - 1) / 2;
    }
    printf("%lld", ans);
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值