大意
给定一些点,求出一共可以组成多少个三角形
思路
50分的思路直接暴力
100分的思路利用三角函数求出所有可以组成的角,再排个序,若其中出现重复的则减去即可
注意要预处理组合数,时间复杂度
O(n2logn)
O
(
n
2
l
o
g
n
)
50分代码
#include<cstdio>
#include<algorithm>
using namespace std;int n,s,xi,yi,xj,yj,xk,yk;
struct node{int x,y;}a[3001];
inline bool cmp(node x,node y){return x.y>y.y;}
signed main()
{
scanf("%d",&n);
for(register int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
sort(a+1,a+1+n,cmp);
for(register int i=1;i<n-1;i++)
for(register int j=i+1;j<n;j++)
for(register int k=j+1;k<=n;k++)
{
xi=a[i].x;yi=a[i].y;
xj=a[j].x;yj=a[j].y;
xk=a[k].x;yk=a[k].y;
if(xi==xj&&xj==xk) continue;
if(yi==yj&&yj==yk) continue;
if(yi-yj==xj-xi&&yj-yk==xj-xk) continue;
if(yj-yi==xi-xj&&yj-yk==xk-xj) continue;//判断
s++;//计算
}
printf("%d",s);//输出
}
AC代码
#include<cstdio>
#include<algorithm>
using namespace std;int n,s,c[3001][3001],x[3001],y[3001],tot,tmp;
long long ans;
double a[3001];
signed main()
{
scanf("%d",&n);
c[0][0]=1;
for(register int i=1;i<=n;i++)//预处理组合数
{
c[i][0]=1;
for(register int j=1;j<=i;j++) c[i][j]=c[~-i][~-j]+c[~-i][j];
}
for(register int i=1;i<=n;i++)
{
tot=0;
scanf("%d%d",x+i,y+i);
x[i]+=30000;y[i]+=30000;
ans+=c[i-1][2];//方案数即为在之前所有的三角形中选出两个与第三个匹配
for(register int j=1;j<i;j++)
{
double s=(x[j]-x[i]==0)?0x3f3f3f3f:(double)(y[j]-y[i])/(double)(x[j]-x[i]);//用这个玩意儿判断是否在一条直线上
a[++tot]=s;
}
sort(a+1,a+1+tot);//排个序
tmp=0;
a[0]=-2147483601;//记得初始化
for(register int j=1;j<=tot+1;j++)
if(a[j]!=a[j-1])
{
ans-=c[j-tmp][2];//去除重复部分
tmp=j;
}
}
printf("%lld",ans);//记得开longlong
}