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; }