1. 程式人生 > >Codeforces 849B Tell Your World (計算幾何)

Codeforces 849B Tell Your World (計算幾何)

continue int ++i 滿足 light size sizeof tar tell

題目鏈接 Tell Your World

題意 給出N個點(i, xi),問是否存在兩條平行的直線,使得每一個點恰好在兩條直線的其中一條上。

每條直線必須穿過至少一個點。

考慮每個點和第1個點的斜率,相同的用並查集弄成一個連通塊。

然後我們枚舉每個連通塊,判斷不在連通塊內的這些點是否在同一條直線上,且斜率必須滿足和另一條相等。

註意特殊情況

1號點單獨占一條直線,其他的點占另一條直線。

這種情況樣例裏就有。

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)

typedef long long LL;

const int N = 1e3 + 10;
const double eps = 1e-8;

LL a[N];
int father[N], b[N], c[N], f[N];
int n, cnt = 0, ans = 0;
double cc[N];
vector <int> v[N];

int getfather(int x){ return father[x] ? father[x] = getfather(father[x]) : x;}

int main(){

	scanf("%d", &n);
	rep(i, 1, n) scanf("%lld", a + i);


	rep(i, 2, n - 1){
		rep(j, i + 1, n){
			if ((LL)(i - 1) * (a[j] - a[1]) == (LL)(j - 1) * (a[i] - a[1])){
				int fa = getfather(i), fb = getfather(j);
				if (fa ^ fb){
					father[fa] = fb;
				}
			}
		}
	}

	rep(i, 2, n){
		int x = getfather(i);
		if (!c[x]){
			c[x] = ++cnt;
			v[cnt].push_back(i);
		}
		else v[c[x]].push_back(i);
	}
	

	ans = 0;
	rep(i, 1, cnt){
		if ((int)v[i].size() == n - 1) continue;
		memset(b, 0, sizeof b);
		double AA = (double)(a[v[i][0]] - a[1]) / (v[i][0] - 1);
		for (auto u : v[i]) b[u] = 1;
		int now = 0;
		rep(j, 2, n) if (!b[j]) f[++now] = j;
		if (now == 1){
			ans = 1;
			break;
		}

		int ff = 0;
		rep(j, 2, now) cc[++ff] = (double)(a[f[j]] - a[f[1]]) / (double)(f[j] - f[1]);
		
		sort(cc + 1, cc + ff + 1);
		bool fl = true;
		rep(j, 1, ff - 1) if (fabs(cc[j + 1] - cc[j]) > eps){
			fl = false;
			continue;
		}

		if (!fl) continue;
		if (fabs(AA - cc[1]) < eps){
			ans = 1;
			break;
		}

	}

	int ff = 0;
	rep(j, 3, n) cc[++ff] = (double)(a[j] - a[2]) / (double)(j - 2);
	

	sort(cc + 1, cc + ff + 1);
	bool fl = true;
	rep(j, 1, ff - 1) if (fabs(cc[j + 1] - cc[j]) > eps){
		fl = false;
		break;
	}

	if (fl){
		double AA = (double)(a[2] - a[1]);
		if (fabs(AA - cc[1]) > eps) ans = 1;
	}
	puts(ans ? "Yes" : "No");
	return 0;
}

Codeforces 849B Tell Your World (計算幾何)