**题意:
给你n个点,问你3点共线的组合数有多少,就是有多少种组合是满足3点共线的。
思路:
**
一开始抱着试1试的态度,暴力了一个O(n^3),结果一如既往的超时了,然后又在刚刚超时的代码上直接加了一个优化,就是如果当前斜率出现的次数小于2次,那么第三重for就不用在跑了,结果,呵呵,又超时了,然后又尝试了一个方法,就是枚举每一个点,求出所有点跟他组成的线段的斜率,记录每个斜率出现的次数,比如当前的斜率0.5出现了8次,那么就Ans + C(8,2) 一开始写的是C(8,3)忘记了当前的这个点必须在线段上,所以wa了一发,最后答案再除以3就行了,因为任意一组情况中的三个点都得到了一个答案,所以除以3.具体的细节看代码。
#include
#include
using namespace std**;
typedef struct
{
double** x ,y;
}NODE;
NODE node[1100];
double mkxl[1100];
map
double** xl(int a ,int b)
{
if(node[a].x == node[b].x) return 1000000000.0;
return (node[a].y - node[b].y) / (node[a].x - node[b].x**);
}
int main ()
{
int** t ,n ,i ,j ;
__int64 Ans;
scanf("%d" ,&t);
while(t--)
{
scanf("%d" ,&n);
for(i = 1 ;i <= n ;i ++)
scanf("%lf %lf" ,&node[i].x ,&node[i].y);
Ans = 0;
for(i = 1 ;i <= n ;i ++)
{
mark.clear();
int nowid = 0;
for(j = 1 ;j <= n ;j ++)
{
if(i == j) continue;
if(++mark[xl(i ,j)] == 1)
mkxl[++nowid] = xl(i ,j);
}
for(j = 1 ;j <= nowid ;j ++)
{
__int64 tmp = mark[mkxl[j]];
if(tmp >= 2)
Ans += tmp * (tmp - 1) / 2;
}
}
printf("%I64d\n" ,Ans / 3);
}
return 0;
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章