您的位置:首页 > 其它

两亲性分子(Amphiphilic Carbon Molecules,Uva 1606)

2016-01-06 20:18 423 查看

原题链接

分析:假设隔板一定经过两点,则可以根据两点的枚举进行统计。首先可以枚举一个基准点,再根据枚举的另一个点进行隔板的枚举对点数进行统计。在进行枚举之前算出其余点基于基准点的极角进行升序排列,之后再进行枚举统计。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
#include<map>
#include<cmath>
#include<sstream>
#include<queue>
#include<cctype>
using namespace std;
typedef long long ll;
const int Max = 100000 + 5;

struct Node {
double rad;
int x,y;
bool operator < (const Node &rhs) {
return rad < rhs.rad;
}
}p[Max],op[Max];

int n,color[Max];

int Left(Node a,Node b) {
return (a.x * b.y - a.y * b.x) >= 0;
}

int solve() {
if(n <= 2) return 2;
int ans = 0;
// 枚举基准点
for(int i=0;i<n;i++) {
int k = 0;
for(int j=0;j<n;j++)
if(i != j) {
// 根据基准点重新计算坐标
p[k].x = op[j].x - op[i].x;
p[k].y = op[j].y - op[i].y;
// 黑点坐标取反,便于统计
if(color[j]) {
p[k].x = -p[k].x;
p[k].y = -p[k].y;
}
// 计算极角
p[k].rad = atan2(p[k].y,p[k].x);
k++;
}
sort(p,p+k);
int cnt = 2;
int L = 0,R = 0;
// 枚举隔板
while(L < k) {
if(L == R) { R = (R + 1) % k; cnt++; }
// 进行条件统计
while(L != R && Left(p[L],p[R])) {
R = (R + 1) % k;
cnt++;
}
cnt--;
L++;
ans = max(cnt,ans);
}
}
return ans;
}
int main(){
while(~scanf("%d", &n) && n){
for(int i=0;i<n;i++) scanf("%d%d%d",&op[i].x,&op[i].y,&color[i]);
printf("%d\n",solve());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: