ABC 248 | E - K-colinear Line
题目描述
给定平面上不相重合的\(N\)个点,计算穿过其中\(K\)个点的线的条数,若有无穷条,输出Infinity
数据范围
- \(1 \le K \le N \le 300\)
- \(\vert X_i \vert, \vert Y_i \vert \le 10^9\)
- \(X_i \neq X_j\)or\(Y_i \neq Y_j\),if \(i \neq j\)
题解
若\(k = 1\),则答案为Infinity
若\(k \ge 2\),由于两点确定一条直线且本题至多有\(300\)个点,可以暴力枚举两个点,然后枚举剩余点是否在该直线上,通过一个二维数组\(st[i][j]\)记录第\(i\)和点与第\(j\)个点所在直线是否被计算,对于在一条直线上的\(n\)个点,两两之间不该被再次计算。
通过\((x_0, y_0)\)的直线可被表示为\((y - y_0) = k(x - x_0)\),判断点\((x_2, y_2)\)是否在\((x_0, y_0)、(x_1,y_1)\)所在直线上,可通过\(\frac{y_2 - y_0}{x_2 - x_0} = \frac{y_1 - y_0}{x_1 - x_0}\),即\((y_2 - y_0) *(x_1 - x_0) = (y_1 - y_0) * (x_2 - x_0)\)
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
typedef long long ll;
using namespace std;
typedef pair<ll, ll> pii;
const int N = 310;
pii a[N];
ll n, k;
bool st[N][N];
vector<int> vec;
int main()
{
scanf("%d%d", &n, &k);
for(int i = 0; i < n; i ++){
ll x, y;
scanf("%lld%lld", &x, &y);
a[i] = {x, y};
}
if(k == 1) puts("Infinity");
else{
int ans = 0;
for(int i = 0; i < n; i ++){
for(int j = i + 1; j < n; j ++){
if(!st[i][j]){
int cnt = 2;
vec.clear();
vec.push_back(i), vec.push_back(j);
for(int l = j + 1; l < n; l ++){
ll x0 = a[i].first, y0 = a[i].second;
ll x1 = a[j].first, y1 = a[j].second;
ll x2 = a[l].first, y2 = a[l].second;
if((y1 - y0) * (x2 - x0) == (y2 - y0) * (x1 - x0)){
vec.push_back(l);
cnt ++;
}
}
for(int x = 0; x < vec.size(); x ++){
for(int y = 0; y < vec.size(); y ++){
st[vec[x]][vec[y]] = true;
}
}
if(cnt >= k) ans ++;
}
}
}
printf("%d\n", ans);
}
return 0;
}

浙公网安备 33010602011771号