题解思路:
本题要求解决出直线经过范围内点个数最大个数,显然我们有(y-y0)=k(x-x0)两点式方程可以得出斜率k,所以只需要遍历每一个点和其他点的k,可以选择用map存贮不同的k值,每次遍历完成后将该循环内部的众数取出,做max比较,即 res = max(res, cnt);但我们要特判k不存在时候的数据记作cnt,之后还要res=max(res,cnt)才能退出一层循环,之后输出++res即可,++res是指将点数输出,因为我们求的是斜率不同值的次数,两个点确定一条斜率,所以最终结果要++!
当然,本题如果倾斜角给出k就知道了,比如把题目改成经过倾斜角为45度的直线最多通过的点数有多少个,那么可以设y=kx+b;k已知,只需要枚举b,将b用map<int,int>mp存贮,输出mp.second最大值就可以了,很明显这个样子出题,题目难度会降低一个档次,思考维度少了,也不需要考虑k是否存在的情况!
完整题解思路:
考虑直线的点斜式y-y1=k(x-x1),枚举每个点作为固定点(x1,y1),再去枚举剩下的点(x,y),对于每一个(x,y)都可以求出一个对应的k。那么对于当前固定点(x1,y1)能构成的所有直线里,与之共线的点的最大个数就是k的众数出现的次数。
令这个次数为
,则最终的答案就是所有
里面的最大值。
计算
的方法与C题类似(就是y=kx+b的情况)
注意:
1.斜率不存在时需要特判
2.计算斜率会用到double,double虽然精度有限,但此题输入的坐标都是整数且都在[-1e9,1e9]的范围内,所以当斜率存在时,
最大为2e9,没有超过double的有效位数16位。并且计算斜率只会用到一次除法运算,所以不会因为double精度(有效位数)不够而导致答案计算错误。
思考:
若输入的坐标仍为整数,但范围是[-1e18,1e18],此时该如何处理?
本题代码如下:
注释部分为一开始只进行一次for导致求出来的斜率均是和前一个比较的,没有和隔几个的比较;然后我第二次隔着比较出现了重复,应该是每次内层循环结束就要比较数量的大小!!!注意此时的map第一个key是double类型
#include<iostream>
#include<queue>
#include<set>
#include<string>
#include<numeric>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<map>
#define int long long
using namespace std;
const int MaxN = 2e5 + 5;
int ans = 0;
int n;
int a[200001];
int b[200001];
using pii = pair<int, int>;
struct jihe {
int a;
int b;
};
struct jihe arr[MaxN];
void solves() {
cin >> n;
map<double, int>mp;
for (int i = 0; i < n; ++i)
{
cin >> arr[i].a >> arr[i].b;
}
int res = 0;
for (int i = 0; i < n; i++) {
map<double, int> mp;
int cnt = 0;
for (int j = 0; j < n; j++) {
if (j == i) continue;
double tmpx = arr[j].a - arr[i].a;
double tmpy = arr[j].b - arr[i].b;
double k;
if (tmpx != 0) {
k = 1.0 * tmpy / tmpx;
mp[k]++;
}
else cnt++;
res = max(res, cnt);
res = max(res, mp[k]);
}
}
cout << ++res << endl;
/* for (int i = 0; i < n; ++i)
{
for (int j = i+1; j < n; ++j)
{
double tempx = arr[j].a - arr[i ].a;
double tempy = arr[j].b - arr[i].b;
if (tempx != 0)
{
double k = 1.0 * tempy / tempx;
mp[k]++;
}
else cnt++;
}
}
int ans = 0;
for (auto& i : mp)ans = max(ans, i.second);
ans = max(ans, cnt);
cout << ans << endl;*/
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
solves();
return 0;
}