B. Tell Your World

http://codeforces.com/contest/849/problem/B

题目是给出n个点,要求把这n个点分成两组,每组都是一条直线。而且这两组不能为空,还要是平行的。

思路:

对于前3个点来说,他们不可能各自一组,因为只能分成2组。

他们有可能同时一组,或者两个点在一组。

这一共就4种情况,然后O(n)判断即可

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = 1e3 + 20;
struct coor {
    LL x, y;
} a[maxn], b[maxn];
int vis[maxn], DFN = 1;
int n;
bool same(int i, int j, int k) {
    return (a[j].y - a[i].y) * (a[k].x - a[i].x) == (a[k].y - a[i].y) * (a[j].x - a[i].x);
}
bool init(int one, int two) {
    ++DFN;
    vis[one] = vis[two] = DFN;
    for (int i = 1; i <= n; ++i) {
        if (vis[i] == DFN) continue;
        if (same(one, two, i)) {
            vis[i] = DFN;
        }
    }
    int lenb = 0;
    for (int i = 1; i <= n; ++i) {
        if (vis[i] == DFN) continue;
        if (lenb == 0) b[++lenb] = a[i];
        else {
            b[++lenb] = a[i];
            if ((a[two].y - a[one].y) * (b[lenb].x - b[1].x) != (b[lenb].y - b[1].y) * (a[two].x - a[one].x)) {
                return false;
            }
        }
    }
    return lenb != 0;
}
void work() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%I64d", &a[i].y);
        a[i].x = i;
    }
    for (int i = 1; i <= 3; ++i) {
        for (int j = i + 1; j <= 3; ++j) {
            if (init(i, j)) {
                printf("Yes
");
                return;
            }
        }
    }
    printf("No
");
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    work();
    return 0;
}
原文地址:https://www.cnblogs.com/liuweimingcprogram/p/7468419.html