传送门:E - K-colinear Line (atcoder.jp)
题意:给N个点,找出线上有K个点及以上的线有几条?
看了一下蒋的思路:先算出所有线
,记录一下
(注意符号,
和
表示同一条线)即可,然后再用每条线遍历每个点看哪些点在线上,最后复杂度
。很好想,但是我的方法可以
(自豪哼哼,虽然大佬肯定不屑于纠结这些没啥用的)
同样是的计算所有线,记录每条线出现次数,出现次数
就表示这条线上面的点有K个以上。
代码如下:
#include<iostream>
#include<cstdio>
#include<map>
#include<vector>
#include <algorithm>
using namespace std;
#define ll long long
const int N = 400;
typedef pair<ll, ll> PII;
ll X[N], Y[N];
map< pair<PII, ll>, 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;
}