暴力题,水一水就过了。。。理论上讲斜率用浮点数表示就行,然而谨慎的人会尽量避开浮点数精度损失可能导致的bug。。。
Point.1斜率为0,斜率不存在
△x为0时不管△y是多少,直线相互平行,算一条;
△y为0时同上。
Point.2 约分
如果分别存△x和△y要化成最简,即二者同除个gcd。为方便排序判重,二者符号相反时要统一一个量的符号,直接同时取相反数没啥好说的。。。
解题思路
很显然了,直接暴力枚举两点连线的斜率,排个序然后去重
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
struct mc
{
int x,y;
bool operator <(const mc a) const
{
return (x<a.x||(x==a.x&&y<a.y));
}
}e[50000],a[205];
int gcd(int x,int y)
{
if (y==0) return x;
else return gcd(y,x%y);
}
int main()
{
// freopen("lines.in","r",stdin);
// freopen("lines.out","w",stdout);
int n;
scanf("%d",&n);
int x,y,cnt=0,m1=0,m2=0;
for (int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
for (int j=1;j<i;j++)
{
int x1=a[i].x,y1=a[i].y;
int x2=a[j].x,y2=a[j].y;
x=x1-x2,y=y1-y2;
if (x==0)
{
m1=1;
continue;
}
if (y==0)
{
m2=1;
continue;
}
cnt++;
if (y)
{
e[cnt].x=x/gcd(x,y);
e[cnt].y=y/gcd(x,y);
}
else
{
e[cnt].x=x;
e[cnt].y=y;
}
if (e[cnt].x<0)
{
e[cnt].x*=-1;
e[cnt].y*=-1;
}
//cout<<x<<' '<<y<<' '<<e[cnt].x<<' '<<e[cnt].y<<endl;
}
}
sort(e+1,e+cnt+1);
// for (int i=1;i<=cnt;i++)
// cout<<' '<<e[i].x<<' '<<e[i].y<<endl;
int i=1,ans=1;
while (e[i].x==0) i++;
int sx=e[i].x,sy=e[i].y;
while(i<=cnt)
{
if (e[i].x==0)
{
ans++;
sx=0;
while (e[i].x==0) i++;
}
if (e[i].x==sx)
{
if (e[i].y==sy)
{
i++;
continue;
}
else
{
ans++;
sy=e[i].y;
i++;
}
}
else
{
ans++;
sx=e[i].x;
sy=e[i].y;
}
}
printf("%d",ans+m1+m2);
return 0;
}