AtCoder Beginner Contest 248 E - K-colinear Line // 计算几何

原题链接:E - K-colinear Line (atcoder.jp)

题意:

给出直角坐标系上N个点(N <= 300),求经过这些点中至少K个点的直线数量,若有无穷多条,则输出"Infinity"。

思路:

  • 两点确定一条直线:

    当K=1时,答案自然是无穷多条。

    当K >= 2时,我们可以枚举两点,求出其确定的直线,再枚举所有点,判断该直线经过的点数是否不少于K。

  • 求直线方程:用直线的一般式方程Ax+By+C=0(普适性)来表示直线。

    已知经过点(x1,y1),(x2,y2),那么A = y2 - y1, B = x1 - x2, C = x2 * y1 - x1 * y2。

    为了方便直线的判重,对参数进行处理(唯一性),使得:ABC三数公因数为1,A > 0 或 A = 0 且 B > 0。

代码参考:

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 310;

int n, k, x[N], y[N];
set<array<int,3>> S;

int gcd(int a, int b)
{
    return b == 0 ? a : gcd(b, a % b);
}

signed main()
{
    cin >> n >> k;
    for(int i = 1; i <= n; i++) cin >> x[i] >> y[i];

    if(k == 1) {
        cout << "Infinity" << endl;
        return 0;
    }

    for(int i = 1; i <= n; i++) {
        for(int j = i + 1; j <= n; j++) {
            // A = y2 - y1, B = x1 - x2, C = x2 * y1 - x1 * y2
            int A = y[j] - y[i], B = x[i] - x[j];
            int C = x[j] * y[i] - x[i] * y[j];
            int g = gcd(gcd(A, B), C);
            A /= g, B /= g, C /= g;
            if(A < 0 || A == 0 && B < 0) {
                A = -A, B = -B, C = -C;
            }
            int cnt = 0;
            for(int k = 1; k <= n; k++) {
                if(A * x[k] + B * y[k] + C == 0) ++ cnt;
            }
            if(cnt >= k) S.insert({A, B, C});
        }
    }
    cout << S.size() << endl;

    return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值