题目链接:
https://wenku.baidu.com/view/d8253e24f90f76c660371ac2.html?from=search
问题描述:
“我该怎么办?”飞行员klux向你求助。事实上,klux面对的是一个很简单的问题,但是他实在是太菜了。Klux 要想轰炸某个区域内的一些地方,它们是位于平面上的一些点,但是klux遇到了抵抗,所以他只能飞一次,而且由于飞机比较破,一旦起飞就只能沿直线飞行,无法转弯。现在他想一次轰炸最多的地
方。
输入:
输入由若干组数据构成,每组数据的第一行是整数n,然后是n行整数对组成(1<n<700),每对整数表示一个点的坐标,且没有一个点会出现两次。当n为0时表示输入结束。
输出:
针对没组数据输出一一个数,它表示一条直线能覆盖的最多的点数
输入样本:
1 1
2 2
3 3
9 10
10 11
输出样本:
3
思路=========================================================================
根据斜率【k = ( y1 - y2 ) / ( x1 - x2 )】以及直线坐标公式【y = k * x + l】获取每两个点组合确定的直线公式,循环套入样本中所有点统计符合公式的点的个数确定【覆盖的最多的点数】;
这里可能要注意的应该是求斜率时由于涉及除法,可能会因为四舍五入而失精度,为求准确不建议分开求出斜率再求偏移量;
List<string> readLineStrings = new List<string> {// 方便测试
"5",
"1 1",
"2 2",
"3 3",
"9 10",
"10 11"
};
int n = int.Parse( readLineStrings[0]);
List<Point> points = new List<Point>();
for (int i = 1; i <= n; i++)
{
string[] point = readLineStrings[i].Split();
double x = double.Parse(point[0]);
double y = double.Parse(point[1]);
points.Add(new Point(x,y));
}
int maxPointCountInLine = 0;// 结果
for (int i = 0; i < points.Count; i++)
{
for (int j = i+1; j < points.Count; j++)
{
double y1 = points[i].Y;
double y2 = points[j].Y;
double x1 =points[i].X;
double x2 = points[j].X;
// k=(y1 - y2) / (x1 - x2);// 斜率
double l = y1 - x1 * (y1 - y2) / (x1 - x2);// 没有一个点会出现两次这里不用验证分母是否为0
int pointCountInLine = 0;
foreach (Point point in points)
{
if (point.Y == point.X * (y1 - y2) / (x1 - x2)+l)
{
pointCountInLine++;
}
}
if (pointCountInLine > maxPointCountInLine)
{
maxPointCountInLine = pointCountInLine;
}
}
}
Console.WriteLine(maxPointCountInLine);
Console.ReadKey();