我在解决算法问题时偶然发现了这个问题。有一个矩形矩阵。
我得到一对位置作为输入,那么如何计算它们是否落在一条直线上,例如。在这种情况下,我得到输入为(d,B)(c,D)(b,F)(a,H),其实际上是直线。 如果我们仔细看到它,短边的计数器会跳过1,而较长边的计数器会跳过2.如果我根据这个逻辑编写我的代码那么,对于更大的矩形或者我是否是一个安全的假设可以面对这个逻辑的问题吗?
我在这里假设倾斜的直线只能是两种类型 1)两个计数器都跳过1,就像方阵的对角线一样。 2)上面讨论的情况,其中计数器在较短的一侧跳过1而在较长的一侧跳过2。
是否有一组点可能直线但不符合上述任何一个条件且它们不在一行或一列中?
答案 0 :(得分:2)
好吧,让我们从两个退化案例开始:
假设您有 3 + 点,并且您想检查它们是否都在同一行。取两个任意点(x1, y1)
和(x2, y2)
。你又有两个案例:
x1 == x2
;检查所有点是否都是xi == x1
x1 != x2
;检查所有点是否满足两个条件:
(y1 - y2) * (xi - x2) == (yi - y2) * (x1 - x2)
(y2*x1 - y1*x2) * (xi - x2) == (y2*xi - yi*x2) * (x1 - x2)
即。所有点都位于同一y = kx + b
行,其中k
和b
来自(x1, y1)
和(x2, y2)
在你的情况下,当A = 1, B = 2, ..., H = 8; a = 1, b = 2, ..., d = 4
我们有
(2, 4)
(4, 3)
(6, 2)
(8, 1)
在同一行上的点。可能的(C#)实现:
private static bool SameLine(IEnumerable<Tuple<int, int>> points) {
if (null == points)
return true;
Tuple<int, int>[] data = points.ToArray();
// i = 2 - first two points are always on the same line
for (int i = 2; i < data.Length; ++i) {
int x1 = data[0].Item1;
int y1 = data[0].Item2;
int x2 = data[1].Item1;
int y2 = data[1].Item2;
int xi = data[i].Item1;
int yi = data[i].Item2;
// y = k * x + b where k = infinity
if (x1 == x2) {
if (xi != x1)
return false;
continue;
}
// Same k in y = k * x + b
if (!((y1 - y2) * (xi - x2) == (yi - y2) * (x1 - x2)))
return false;
// Same b in y = k * x + b
if (!((y2 * x1 - y1 * x2) * (xi - x2) == (y2 * xi - yi * x2) * (x1 - x2)))
return false;
}
return true;
}
测试
Tuple<int, int>[] test = new Tuple<int, int>[] {
new Tuple<int, int>(2, 4),
new Tuple<int, int>(4, 3),
new Tuple<int, int>(6, 2),
new Tuple<int, int>(8, 1),
};
// Same line
Console.Write(SameLine(test) ? "Same line" : "different lines");