题目链接
题目大意
有n个点,每两个点可以连成一条直线,问你这些直线相交的点有多少个
解题思路
用两点算出来每条直线的一般式,用map去重,然后两两判边有没有交点,有交点就算一次相交,最后输出就好啦
map里面写结构体的时候,结构体要重载。
友情提示:这个代码要用C++11运行,不然会智障掉。。。。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
int tot=0;
struct linee
{
double a,b,c;
linee(){}
linee(double _a,double _b,double _c)
{
a=_a;
b=_b;
c=_c;
}
bool operator < (const linee &x) const
{
if(a==x.a)
{
if(b==x.b)
return c>x.c;
return b>x.b;
}
return a>x.a;
};
linee li[10005];
pair<double,double>node[55];
map<linee,int>ma;
map<pair<double,double>,int>dian;
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf %lf",&node[i].first,&node[i].second);
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
int x1=node[i].first,y1=node[i].second;
int x2=node[j].first,y2=node[j].second;
int g=__gcd(y1-y2,x1-x2);
double A=-(y2-y1)/g,B=(x2-x1)/g,C=-y1*B-x1*A;//直线的一般式的A,B,C
if(!ma[linee(A,B,C)])//去重
{
li[tot++]=linee(A,B,C);
ma[linee(A,B,C)]=1;
}
}
}
int ans=0;
for(int i=0;i<tot;i++)
{
for(int j=i+1;j<tot;j++)
{
double A1=li[i].a,B1=li[i].b,C1=li[i].c;
double A2=li[j].a,B2=li[j].b,C2=li[j].c;
double m=A1*B2-A2*B1;
if(m!=0)//相交
{
ans++;
}
}
}
printf("%d\n",ans);
return 0;
}