Educational Codeforces Round 41
阿新 • • 發佈:2018-04-08
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; constView Codeint 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; }
Educational Codeforces Round 41