【问题标题】:Logical Explanation to the below c/c++ solution以下 c/c++ 解决方案的逻辑解释
【发布时间】:2013-10-28 07:59:18
【问题描述】:

有人可以向我解释一下为什么在以下解决方案中使用 GCD:

http://www.codechef.com/viewsolution/2849602(用于 c)

http://www.codechef.com/viewsolution/2849324(用于 c++)

提问:http://www.codechef.com/ACMKAN13/problems/LINEPROB

狙击手站在 2D XY 平面上的点 (x1, y1)。他从他的位置向点 (x2, y2) 射击。你可以假设所有的点都是整数。

考虑由 XY 平面上的整数点形成的二维网格。 Sniper 和 Target 的位置是这个网格中的格点。狙击手射出的子弹会沿着从 (x1, y1) 到 (x2, y2) 的直线轨迹。子弹不会超过 (x2, y2)。

考虑当狙击手站在 (1, 1) 并且目标位于 (4, 3) 时子弹的轨迹。

注意子弹的轨迹如何接触 4 个单元格。当且仅当子弹将进入单元格时,才认为该单元格被轨迹触及。子弹的轨迹触及了多少细胞?

 输入

第一行包含一个整数 T,即测试用例的数量。以下 T 行中的每一行都包含一个测试用例。每个测试用例包含 4 个整数 x1、y1、x2 和 y2。整数由单个空格字符分隔。 输出

对于每个测试用例,输出一行,包含子弹从 (x1, y1) 到 (x2, y2) 的轨迹所触及的单元格数。请记住,当且仅当子弹进入单元格时,才认为一个单元格被弹道接触 - 仅接触一侧是不够的。 约束

0

示例输入

3 0 0 3 2 0 0 2 2 0 0 1 0

样本输出

4 2 0

【问题讨论】:

  • 是的,已经结束了,但是我只是想知道使用GCD背后的逻辑。我其实很喜欢这个解决方案,但找不到理由。

标签: c++ c algorithm math geometry


【解决方案1】:

在解释使用 gcd 背后的逻辑之前,我想澄清一下,这可能不是这段代码的作者所想的确切方式。
首先,我在该代码中看不到任何max 函数的使用。
说明:
我们假设

  1. 狙击手位于(0,0),目标位于(3,3)。很明显子弹的弹道会碰到2细胞。
    备注:当狙击手和目标在x = y线上或平行时,接触的细胞比那个少一个纵坐标(或横坐标)。 (这等于子弹行进距离的xy 分量的总和,减去子弹行进距离的xy 分量的GCD .)
  2. 狙击手在(0,0),目标在(0,3)(3,0)。再次看到图片,子弹的轨迹会触及0细胞。
    备注:当狙击手和目标在线时xy或与xy 平行,触摸的单元格是一个0。 (这等于子弹行进距离的xy 分量的总和,减去子弹行进距离的xy 分量的GCD .)
  3. 狙击手位于(1,1),目标位于(4,3)。很明显子弹的轨迹会碰到4单元格。
    备注:在所有其他情况下,单元格的数量等于xy分量之和子弹行进的距离减去子弹行进距离的xy 分量的GCD。

【讨论】:

    【解决方案2】:

    解决方案背后的逻辑是:

    子弹沿 X 轴穿过的方块数,加上
    子弹沿 Y 轴穿过的块数,减去
    被过度计算的块数

    给定点(X1, Y1)(X2, Y2),让A1 = abs(X1 - X2)A2 = abs(Y1 - Y2)。那么,不失一般性,我们可以考虑(0, 0)(A1, A2)这两个点。

    请注意,A1 表示子弹沿 X 轴穿过的块数。但是,这也是网格上间隔(0, A1] 上子弹所触及的垂直线数。同理,A2表示子弹沿Y轴经过的块数,也表示子弹在区间(0, A2]上触及的水平线数。

    当被视为触及线的数量时,更容易看出为什么需要减去一些数字。需要减去的数字是对应于在垂直和水平线交叉处发生的触摸的数字。出现的次数由A1A2 的 GCD 计算。特别是,它发生在1 .. GCD(A1,A2) 中的k(k * A1/GCD(A1,A2), k * A2/GCD(A1,A2)) 点。

    【讨论】:

    • 能否请您解释一下最后一部分的交集也与数字的gcd相同。
    • @user1675947:我想我在最后一句话中解释了这一点。你有什么特别不清楚的地方?
    • 为什么线的交点也等于数字的gcd?
    • 最后一句话解释了原因。 GCD 平均分为A1A2。因此,交点发生在每个 A1/GCD 右侧,A2/GCD 向上。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-15
    • 1970-01-01
    相关资源
    最近更新 更多