BC C Revenge of Collinearity hdu 5020

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=5020

題目描述:給你n 個點,兩兩不同n<1000,求所有3個點共線的集合有多少個。保證75%數據 n<=100,有33組數據

解題思路:一開始,我想先把所有的斜率都算出來,離散化,搞一搞,但是內存只有32K,靠,真坑。。。

正解是,枚舉每個點,作爲共線三點最左最下的點,然後極角排序,相同斜率的點爲n,ans+= C(n,2)

//#pragma comment(linker,"/STACK:102400000,102400000")
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define ll long long
#define db double
#define PB push_back
#define lson k<<1
#define rson k<<1|1
using namespace std;

const int N = 100005;

struct Point
{
    ll x,y;
    Point (ll _x=0,ll _y=0):x(_x),y(_y){}
    void input()
    {
        scanf("%I64d%I64d",&x,&y);
    }
    ll operator * (const Point &t) const
    {
        return x*t.y-t.x*y;
    }
    Point operator - (const Point &t) const
    {
        return Point(x-t.x,y-t.y);
    }
} p[N],a[N];

Point pbase;
bool polarsort(const Point &c,const Point &d)
{
    return (c-pbase)*(d-pbase)>0;
}

int main()
{
#ifdef PKWV
    freopen("in.in","r",stdin);
#endif // PKWV
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++) p[i].input();
        int ans=0;
        for(int i=0;i<n;i++)
        {
            int cnt=0;
            for(int j=0;j<n;j++)
            {
                if(i!=j&&(p[j].x>p[i].x||p[j].x==p[i].x&&p[j].y>=p[i].y))
                    a[cnt++]=p[j];
            }
            pbase=p[i];
            sort(a,a+cnt,polarsort);
            for(int j=0;j<cnt;)
            {
                int k=j;
                int num=0;
                while(k<cnt&&(a[k]-pbase)*(a[j]-pbase)==0) k++,num++;
                if(num>1)
                {
                    ans+=num*(num-1)/2;
                }
                j=k;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章