题意:平面上有n个点,每一个点为白点或者黑点。现在要放置一个隔板,使得隔板的一侧白点加上另一侧黑点的总数最大。
思路:这个题借鉴了这位博主的做法http://blog.csdn.net/u014800748/article/details/47952253
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#define MAXN 1010
#define MAXE 210
#define INF 10000000
#define MOD 1000000007
#define LL long long
#define pi acos(-1.0)
using namespace std;
struct Point {
int x;
int y;
double rad;
bool operator<(const Point &p) const { return rad < p.rad; }
} p[MAXN], point[MAXN];
int color[MAXN];
int n;
bool check(Point p1, Point p2) { return p1.x * p2.y - p1.y * p2.x >= 0; }
int solve() {
if (n <= 2)
return 2;
int ans = 0;
for (int i = 0; i < n; ++i) {
int num = 0;
for (int j = 0; j < n; ++j) {
if (j != i) {
p[num].x = point[j].x - point[i].x;
p[num].y = point[j].y - point[i].y;
if (color[j]) {
p[num].x = -p[num].x;
p[num].y = -p[num].y;
}
p[num].rad = atan2(p[num].y, p[num].x);
num++;
}
}
sort(p, p + num);
int L = 0, R = 0, cnt = 2;
while (L < num) {
if (L == R) {
R = (R + 1) % num;
cnt++;
}
while (L != R && check(p[L], p[R])) {
R = (R + 1) % num;
cnt++;
}
L++;
cnt--;
ans = max(ans, cnt);
}
}
return ans;
}
int main() {
std::ios::sync_with_stdio(false);
while (cin >> n && n) {
for (int i = 0; i < n; ++i)
cin >> point[i].x >> point[i].y >> color[i];
cout << solve() << endl;
}
return 0;
}
/*
3
0 0 0
0 1 0
2 2 1
4
0 0 0
0 4 0
4 0 0
1 2 1
7
-1 0 0
1 2 1
2 3 0
2 1 1
0 3 1
1 4 0
-1 2 0
0
*/