题目链接: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;
}