POJ 1118 Lining Up

枚举,排序。

先将所有点按双关键字排序,然后枚举线的顶点$P$,剩余的点以$P$为中心进行极角排序,可以取个$gcd$,这样一样的点就排在一起了,然后统计一下更新答案。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-8;
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c = getchar(); x = 0;while(!isdigit(c)) c = getchar();
    while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar();  }
}

const int maxn=800;
int n,ans;
struct X{LL x,y;}s[maxn],t[maxn];

LL gcd(LL a,LL b)
{
    if(b==0) return a;
    return gcd(b,a%b);
}

bool cmp(X a,X b)
{
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}

LL ABS(LL a)
{
    if(a<0) a=-a;
    return a;
}

int main()
{
    while(~scanf("%d",&n))
    {
        if(n==0) break; ans=1;
        for(int i=1;i<=n;i++) scanf("%lld%lld",&s[i].x,&s[i].y);
        sort(s+1,s+1+n,cmp);
        for(int i=1;i<=n;i++)
        {
            int sz=0;
            for(int j=i+1;j<=n;j++)
            {
                t[sz].x=s[j].x-s[i].x;
                t[sz].y=s[j].y-s[i].y;
                LL GCD=gcd(ABS(t[sz].x),ABS(t[sz].y));
                t[sz].x=t[sz].x/GCD;
                t[sz].y=t[sz].y/GCD;
                sz++;
            }

            if(sz==0) continue;
            sort(t,t+sz,cmp);

            int k=1;
            for(int i=1;i<sz;i++)
            {
                if(t[i].x==t[i-1].x&&t[i].y==t[i-1].y) k++;
                else  ans=max(ans,k+1),k=1;
            }
            ans=max(ans,k+1);
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2016-09-01 22:22  Fighting_Heart  阅读(141)  评论(0编辑  收藏  举报