AtCoder Beginner Contest 248 E - K-colinear Line // 計算幾何
阿新 • • 發佈:2022-04-17
原題連結: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。
程式碼參考:
//Jakon:計算幾何 #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 * y2int 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; }