Educational Codeforces Round 41

Posted zengwangli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 41相关的知识,希望对你有一定的参考价值。

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的主要内容,如果未能解决你的问题,请参考以下文章

Educational Codeforces Round 7 A

Educational Codeforces Round 7

Educational Codeforces Round 90

Educational Codeforces Round 33

Codeforces Educational Codeforces Round 54 题解

Educational Codeforces Round 27