Official

E - K-colinear Line Editorial by en_translator


If \(K=1\), any line passing through one of the \(N\) points satisfies the condition. Since \(N\geq 1\) is guaranteed, there are infinitely many of them.:w
Specifically, let \((x_0,y_0)\) be one of the \(N\) points; then for any real number \(a\), any line represented as \(y-y_0=a(x-x_0)\) satisfies the condition.

On the other hand, given two distinct points, one can uniquely determine the line passing through the two points, so there are at most \(\frac{N(N-1)}{2}\) liens that passing through \(2\) or more of the \(N\) points. It is enough to check each of them if how many of the \(N\) points it passes through.

Here, a point \(P\) \((x,y)\) is on the line passing through two distinct points \(A\) \((x_0,y_0)\) and \(B\) \((x_1,y_1)\) if and only if there exists a real number \(k\) such that \(\overrightarrow{AP}=k\overrightarrow{AB}\), which can be determined by checking if \((x_1-x_0)(y-y_0)\) and \((y_1-y_0)(x-x_0)\) are equal.

Therefore, each decision problem can be solved in an \(O(1)\) time, so we can count the number of points on each line in an \(O(N)\) time. Since there are \(O(N^2)\) lines, the total time complexity is \(O(N^3)\), which is fast enough to solve the problem. Be careful not to count the same line more than once.

Sample code in C++:

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

long long px[300];
long long py[300];
bool flag[300][300];

bool colinear(int a, int b, int c) {
	long long val1 = (py[b] - py[a])*(px[c] - px[a]);
	long long val2 = (px[b] - px[a])*(py[c] - py[a]);
	return (val1 == val2);
}

int main(void) {
	int n, k, cnt, ans;
	vector<int>list;

	cin >> n >> k;
	for (int i = 0; i < n; i++)cin >> px[i] >> py[i];

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

	for (int i = 0; i < n; i++)for (int j = i + 1; j < n; j++)flag[i][j] = true;
	ans = 0;

	for (int i = 0; i < n; i++) {
		for (int j = i + 1; j < n; j++) {
			if (flag[i][j]) {
				cnt = 2;
				list.clear();
				list.push_back(i);
				list.push_back(j);
				for (int ii = j + 1; ii < n; ii++) {
					if (colinear(i, j, ii)) {
						cnt++;
						list.push_back(ii);
					}
				}
				for (int ii = 0; ii < cnt; ii++)for (int jj = ii + 1; jj < cnt; jj++)flag[list[ii]][list[jj]] = false;
				if (cnt >= k)ans++;
			}
		}
	}

	cout << ans << endl;
	return 0;
}

posted:
last update: