分析:每次枚举一个点作为基准点,然后求其他点与这个基准点的夹角,再排一遍序,按照角度从小到大排序,接下来以基准点和其中一个点的连线开始逆时针扫描一遍,直到基准点和另一个点的连线和开始的那条线之间的角度大于等于180停止,这样就可以了,我也看了好一会儿题解才看懂,具体看代码。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define LL long long
using namespace std;
const int maxn=1005;
struct Point
{
int x,y;
double rad;
bool operator<(const Point &rhs)const{
return rad<rhs.rad;
}
}op[maxn],p[maxn];
int n,color[maxn];
bool left(Point A,Point 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(j!=i){
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 L=0,R=0,cnt=2;
while(L<k){
if(R==L){
R=(R+1)%k;
cnt++;
}
while(R!=L&&left(p[L],p[R])){
R=(R+1)%k;cnt++;
}
cnt--;
L++;
ans=max(ans,cnt);
}
}
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;
}