[洛谷P4385][COCI2009]Dvapravca(咕咕咕)

题目大意:很早以前做的题

题解:

卡点:

C++ Code:

#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <algorithm>
#include <random> 
#include <cstdio>
#include <cstdlib>
#include <ctime>
#define maxn 1010
#define long
const long double eps = 1e-8;
inline long double abs(long double x) { return x < 0 ? -x : x; }

struct Point {
	int x, y;
	bool isR;
	long double b;
	Point() { }
	Point(int __x, int __y, bool __isR) : x(__x), y(__y), isR(__isR), b(__x) { }
	inline bool operator == (const Point &rhs) const {
		return abs(b - rhs.b) < eps;
	}
} P[maxn];
inline long double slope(const Point &lhs, const Point &rhs) {
	return (lhs.y - rhs.y) / static_cast<long double> (lhs.x - rhs.x);
}
inline bool cmp(int a, int b) { return P[a].b < P[b].b; }
inline int sign(long double x) { return x < -eps ? -1 : x > eps; }

std::mt19937 rd(time(0));
int n, totR, totB;
int R[maxn], B[maxn], rnk[maxn];
int ans;

void calc() {
	std::sort(rnk + 1, rnk + n + 1, cmp);
	for (int l = 1, r, cnt[2], res = 0; l <= n; l = r) {
		r = l;
		cnt[0] = cnt[1] = 0;
		while (r <= n && P[rnk[l]] == P[rnk[r]]) 
			++cnt[P[rnk[r]].isR], ++r;
		res += cnt[1];
		ans = std::max(ans, res);
		if (cnt[0]) res = cnt[1];
	}
}
void solve() {
	int __B = rd() % totB, __R = rd() % totR;
	Point _R = P[R[__R]], _B = P[B[__B]];
	if (_R.x == _B.x) return ;
	const long double k = slope(_R, _B), b = _R.y - _R.x * k;
	for (register int i = 1; i <= n; ++i) P[i].b = P[i].y - P[i].x * k;
	long double min = 1e20, max = -1e20;
	for (int *i = B; i != B + totB; ++i) {
		int __s = sign(P[*i].b - b);
		if (__s) {
			if (__s == 1) min = std::min(min, P[*i].b);
			else max = std::max(max, P[*i].b);
		}
	}
	int resm = 1, resM = 1;
	for (int *i = R; i != R + totR; ++i) {
		int __s = sign(P[*i].b - b);
		if (__s) {
			if (__s == 1) resM += (P[*i].b <= min + eps);
			else resm += (P[*i].b >= max - eps);
		}
	}
	ans = std::max(ans, std::max(resm, resM));
}

int main() {
	scanf("%d", &n);
	for (int i = 1, x, y; i <= n; ++i) {
		static char ch;
		scanf("%d%d%1s", &x, &y, &ch);
		P[i] = Point(x, y, ch == 'R');
		rnk[i] = i;
		if (ch == 'R') R[totR++] = i;
		else B[totB++] = i;
	}
	if (totB == 0 || totR == 0) {
		printf("%d
", totR);
		return 0;
	}
	calc();
	while (true) {
		for(int i = 1; i <= 10; ++i) solve();
		if (clock() / static_cast<double> (CLOCKS_PER_SEC) > 0.998) break;
	}
	printf("%d
", ans);
	return 0;
}

  

原文地址:https://www.cnblogs.com/Memory-of-winter/p/11402347.html