Description
Input
Sample Input
6
0 1 0
-5 3 0
-5 -2 25
0 1 -3
0 1 -2
-4 -5 29
Output
Sample Output
10
题目大意
给你一堆直线,求它们能构造出多少个三角形。
思路
看到题目给出的斜率式子:
A
i
∗
x
+
B
i
∗
y
+
c
i
=
0
Ai*x+Bi*y+ci=0
Ai∗x+Bi∗y+ci=0
移项后:
A
i
∗
x
+
c
i
=
−
B
i
Ai*x+ci=-Bi
Ai∗x+ci=−Bi
两边同时取相反数再除
B
i
Bi
Bi:
y
=
−
a
i
/
b
i
−
c
i
/
b
i
y=-ai/bi-ci/bi
y=−ai/bi−ci/bi
所以第i条直线斜率为:
−
a
i
/
b
i
-ai/bi
−ai/bi
我们又可以知道,一个不合法的方案即为两条线平行或三条线平行的方案数,两条直线互相平行即为斜率相同。
而总方案数为:
C
(
n
,
3
)
C(n,3)
C(n,3)
所以答案即为
C
(
n
,
3
)
C(n,3)
C(n,3)减去不合法方案数。
CODE
//L.E.M.T专用水印
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
long long f[500005][10],sum,mo=1e9+7;
long double g[500005];
int n,a,b,c,s;
int main() {
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d%d%d",&a,&b,&c),g[i]=(1.0*a)/(1.0*b);//求斜率
f[1][1]=1;
for (int i=2;i<=n+1;i++) for (int j=1;j<=5;j++) f[i][j]=(f[i-1][j]+f[i-1][j-1]+mo)%mo;//杨辉三角预处理组合数
sort(g+1,g+1+n),s=1;
for (int i=2;i<=n;i++)
if (g[i]==g[i-1]) s++;
else sum=(sum+(f[s+1][3]*(n-s)+mo)%mo+(f[s+1][4]+mo)%mo+mo)%mo,s=1;//sum为不合法方案数
sum=(sum+(f[s+1][3]*(n-s)+mo)%mo+(f[s+1][4]+mo)%mo+mo)%mo;
printf("%lld",(f[n+1][4]-sum+mo)%mo);
}