小梁旅途的第一站,来到了杰尼龟兄弟的栖息地,正巧赶上杰尼龟兄弟们在举行神奇的数学游戏,它们把广阔的湖面当做二维坐标系,他们分别站在某一点向某一方向发射高压水枪,这些高压水枪相互穿透,构成了多个交点。
现在小梁通过建模,把每道高压水枪抽象成了yi=ki*xi+bi的直线,现在她想知道那些高压水枪能构成多少个不同的交点
输入描述:
第一行输入一个整数n(1≤n≤100),表示杰尼龟兄弟的数量
下面n行每行包括两个整数,ki和bi,其含义和直线方程相同
对所有的ki和bi在64位整形的范围内.
输出描述:
如果不存在交点输出"No Fire Point." (不包括引号)
否则输出一个整数表示不同交点的个数。
示例1
输入
2
1 0
-1 2
输出
1
计算几何,其实只要判断斜率不一样就有交点了,但主要是点是否有重复以及精度问题。
由于数据量不大,使用遍历就能解决。
关于精度:double类型使用“==”判断wa了一次,相减 <eps 也wa了一次,最后发现是没加fabs取绝对值,也太蠢了。
#include<bits/stdc++.h>
using namespace std;
const long double eps=1e-8;
typedef long long ll;
struct point{
double x,y;
}p[10005];
int main()
{
ios::sync_with_stdio(false);
ll n,ans=0;
cin>>n;
ll k[105],b[105];
for(int i=0;i<n;i++)cin>>k[i]>>b[i];
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
if(k[i]!=k[j]){
double ex=double(b[j]-b[i])/(k[i]-k[j]);
double ey=(double)k[i]*ex+b[i];
int flag=1;//判断是否是重复的点
for(int k=0;k<ans;k++){
if(fabs(p[k].x-ex)<eps&&fabs(p[k].y-ey)<eps){
flag=0;//是重复
break;
}
}
if(flag){//不是重复
p[ans].x=ex;
p[ans].y=ey;
ans++;
//cout<<"("<<ex<<","<<ey<<")"<<endl;
}
}
}
}
if(ans)cout<<ans<<endl;
else cout<<"No Fire Point."<<endl;
return 0;
}
/*
6
1 0
-1 2
0 1
2 3
4 6
-10 5
输出:13
*/