码迷,mamicode.com
首页 > 其他好文 > 详细

Educational Codeforces Round 41

时间:2018-04-08 00:14:21      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:在线   round   cout   space   pre   isp   直线   hid   code   

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

标签:在线   round   cout   space   pre   isp   直线   hid   code   

原文地址:https://www.cnblogs.com/ZengWangli/p/8735443.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!