1. 程式人生 > >Educational Codeforces Round 41

Educational Codeforces Round 41

std rst ems make spa esp blog 是否 using

D. Pair Of Lines

題目大意:

給n個點,問是否存在兩條直線(可以為同一條)能覆蓋所有的點。

解題思路:

首先一個或者兩個或者三個點都是肯定可以用兩條線覆蓋的。
如果點的個數大於等於三個,那麽我們已經可以確定至少一條線的:
點1和點2可能在一條線上,點2和點3可能在一條線上,點3和點1可能在一條線上。
我們試著確定其中一條線後,去掉在線上的所有點,剩下的點肯定在另一條線上,這樣利用剩下的點就可以確定另一條直線。
能找到這兩條線輸出"YES",否則,如果大於等於3條線,輸出"NO".

代碼:

技術分享圖片
using namespace std;

typedef long long LL;

const
int MAXN = 100000 + 10; typedef pair<int, int> pii; pii p[MAXN]; bool fir[MAXN]; int n; inline pii operator-(const pii& a, const pii& b) { return make_pair(a.first - b.first, a.second - b.second); } inline LL cross(const pii& a, const pii& b) { return 1LL * a.first * b.second - 1LL * a.second * b.first; }
bool check(const pii& a, const pii& b) { memset(fir, 0, sizeof fir); for (int i = 0; i < n; i++) { if (cross(b - a, p[i] - a) == 0) fir[i] = 1; } int p1 = -1, p2 = -1; for (int i = 0; i < n; i++) if (!fir[i]) { if (p1 == -1) p1 = i; else if (p2 == -1
) p2 = i; } if (p2 == -1) return true; else { for (int i = 0; i < n; i++) if (!fir[i]) { if (cross(p[p2] - p[p1], p[i] - p[p1]) != 0) return false; } return true; } } int main() { while (cin >> n) { for (int i = 0; i < n; i++) { cin >> p[i].first >> p[i].second; } if (n == 1 || n == 2 || n == 3) cout << "YES\n"; else { if (check(p[0], p[1]) || check(p[1], p[2]) || check(p[0], p[2])) { cout << "YES\n"; } else { cout << "NO\n"; } } } return 0; }
View Code

Educational Codeforces Round 41