题目要求
游戏场景(二维平面)上有n个战斗点,求最多有多少点在同一条直线上。
输入描述:
输入包含若干行,每组数据的第一行为正整数n,代表点的个数。
剩下n行为点的坐标。
输出描述:
输出为在同一条直线上的输入点数(int)
样例:
输入
4
1 2
3 6
0 0
1 3
输出
3
思路:
使用自定义结构体point表示二维点的坐标,vector<point>用来存储输入的点的坐标。
若输入点的个数n小于等于二,则直接输出n,否则定义map<double,int>分别存储斜率和该斜率的点的个数。
接下来进行双重for循环,第一层for循环对每个i= 0~n - 1遍历,先将map和same置为空,第二层循环计算该点和其余各个点的斜率以及相同斜率的点的个数,将相同点个数存储在same中,每个斜率和等于该斜率的点的个数存储map<double,int>中。
第二层for循环结束后,统计map中相同斜率的点加上same是否大于num,若大则更新num。
对每个点都循环结束后,输出num则为最多在一条直线上的点的个数。
#include <iostream>
#include <string>
#include <vector>
#include <map>
#define INT_MIN -9999
#define INT_MAX 9999
using namespace std;
struct point
{
int x;
int y;
};
int reslove(vector<point> points)
{
int len = points.size();
if (len <= 2)
return len;
map<double, int> m;
int num = INT_MIN;
int count = 0;
for (int i = 0; i < len - 1; ++i)
{
m.clear();
int same = 0;
//m[(double)INT_MIN] = 1;
for (int j = i + 1; j < len; ++j)
{
if (points[i].x == points[j].x&&points[i].y == points[j].y)//若两点相同,则same++
{
same++;
continue;
}
double rate;
if (points[j].x - points[i].x == 0)//若斜率无限大,则将值设为INT_MAX
{
rate = INT_MAX;
}
else
{
rate = (double)(points[j].y - points[i].y) / (double)(points[j].x - points[i].x); //计算斜率
}
if (m.find(rate) != m.end())
m[rate] += 1;//若m中存在rate,则加1
else
m[rate] = 2;//若m中不rate存在,则有两点,加2
}
for (auto c : m)
{
num = c.second + same > num ? c.second + same : num;
}
}
return num;
}
int main()
{
int n;
cin >> n;
vector<point> points;
for (int i = 0; i < n; ++i)
{
point p;
cin >> p.x >> p.y;
points.push_back(p);
}
int num = reslove(points);
cout << num;
return 0;
}