http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4481
枚举每一个点作中心,将一条直线绕该点旋转,动态修改两侧点数。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=1000+5;
struct node
{
int x,y;
double rad;
bool operator<(const node &a)const
{
return rad<a.rad;
}
}op[maxn],p[maxn];
int n,color[maxn];
bool 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(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(l!=r&&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;
}