POJ4072多点共线问题
有N(1<=n<=100)个互不重合的点,并给出它们的坐标(xi,yi),问这些点是否在同一直线上。
Input
第一行是测试的组数T(1<=T<=100),其后是T组数据,每组数据第一行是该组数据点的数量N,后面跟着N行,每行代表一点的坐标,由两个数字构成,这两个数字之间由空格隔开。
Output
有T行,每行对应输入的一组数据,如果该组数据中的点在同一直线上,则该行输出True,否则输出False。
Sample Input
1
3
0 0
2 2
1 1
Sample Output
True
开始的解题思路是从第二个点开始分别与第一个点求斜率,每求出一个一个斜率便插入到set中,最后判断set大小是否为1。
错误原因:1.没有考虑斜率无穷大的情况,例如(0,0),(0,1),(0,2)这三个点求K值时,分母为0.
所以计算几何的题尽量不要考虑斜率,尝试向量内积和外积解决问题,前期还是要多做题积累经验。。。
第一次错误的代码:
#include<bits/stdc++.h>
using namespace std;
struct node{
float x,y;
};
int main()
{
set<float>se;
node d[1000];
int t;
int n;
cin>>t;
while(t--)
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>d[i].x>>d[i].y;
}
for(int i=1;i<n;i++)
{
float st=(d[i].y-d[0].y)/(d[i].x-d[0].x);
se.insert(st);
}
if(se.size()==1)
cout<<"True"<<endl;
else
cout<<"False"<<endl;
}
return 0;
}
AC代码:
#include<iostream>
using namespace std;
double temp[105][2];
int t;
int n;
int main()
{
cin >> t;
while(t -- )
{
int flag = 1;
cin >> n;
for(int i = 0;i < n;i ++ )
{
for(int j = 0;j < 2;j ++ )
{
cin >> temp[i][j];
}
}
for(int i = 2;i < n;i ++ )
{
if((temp[i][1] - temp[0][1]) * (temp[1][0] - temp[0][0]) != (temp[i][0] - temp[0][0]) * (temp[1][1] - temp[0][1]))//用方向向量解题成比例,实质上还是直线斜率
{
flag = 0;
break;
}
}
if(flag){cout<<"True"<<endl;}
else{cout<<"False"<<endl;}
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
struct node{
float x,y;
};
int main()
{
node d[1000];
int t;
int n;
cin>>t;
while(t--)
{
int flag=1;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>d[i].x>>d[i].y;
}
for(int i=1;i<n-1;i++)
{
if((d[i].y-d[0].y)*(d[i+1].x-d[0].x)!=(d[i+1].y-d[0].y)*(d[i].x-d[0].x))//将求斜率的除法转化为乘法的形式,一方面减少误差,另一方面避免了斜率无穷大的情况
{
flag=0;
break;
}
}
if(flag) cout<<"True"<<endl;
else cout<<"False"<<endl;
}
return 0;
}//AC