AtCoder Beginner Contest 248 E - K-colinear Line

传送门:E - K-colinear Line (atcoder.jp)

题意:给N个点,找出线上有K个点及以上的线有几条?

1\leq K\leq N \leq 300

看了一下蒋的思路:先O(n^2)算出所有线ax+by+c=0,记录一下a, b, c(注意符号,a, b, c-a, -b, -c表示同一条线)即可,然后再用每条线遍历每个点看哪些点在线上,最后复杂度O(n^3)。很好想,但是我的方法可以O(n^2 \log{n})(自豪哼哼,虽然大佬肯定不屑于纠结这些没啥用的)

同样是O(n^2)的计算所有线,记录每条线出现次数,出现次数\geq \sum {K-1}就表示这条线上面的点有K个以上。

代码如下:

#include
#include
#include
#include
#include 
using namespace std;
#define ll long long
const int N = 400;
typedef pair PII;
 
ll X[N], Y[N];
map< pair, int> mp;
ll gcd(ll a, ll b) {
    if (b == 0) return a;
    return gcd(b, a % b);
}
int main() {
    ll k, n;
    scanf("%lld%lld", &n, &k);
    for (int i = 0; i < n; i++) {
        // ll x, y;
        scanf("%lld%lld", X+i, Y+i);
    }
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            ll x1 = X[i], y1 = Y[i], x2 = X[j], y2 = Y[j];
            ll a = y2 - y1, b = x1 - x2;
            ll g = abs(__gcd(a, b));
            // node tmp;
            a /= g;
            b /= g;
            ll c = -(a * x1 + b * y1);
            if (a < 0) {
                a = -a;
                b = -b;
                c = -c;
            }
            if(a==0 && b<0){
                b =-b;
                c =-c;
            }
            if (mp[{{a,b},c}]!=0) {
                mp[{{a,b},c}]++;
            }
            else {
                mp[{{a,b},c}] = 1;
            }
        }
    }
    ll ans = 0;
    ll num = (k-1)*k/2;
    for (auto it : mp) {
        if (it.second >= num) ans++;
    }
    if(k<=1) printf("Infinity\n");
    else printf("%lld\n", ans);
    return 0;
}

你可能感兴趣的:(学习笔记c++,atcoder题解,c++,算法)