以下c / c ++解决方案的逻辑解释

时间:2013-10-19 14:38:10

标签: c++ c algorithm math geometry

有人可以向我解释为什么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平面上的整数点形成的2D网格。狙击手和目标的位置是该网格中的格点。狙击手射击的子弹将遵循从(x1,y1)到(x2,y2)的直线轨迹。子弹不会超过(x2,y2)。

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

enter image description here

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

 输入

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

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

0< T< 10100 0≤x1,y1,x2,y2≤1000000000

示例输入

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

示例输出

4 2 0

2 个答案:

答案 0 :(得分:4)

解决方案背后的逻辑是:

  

子弹穿过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计算。特别是,它发生在(k * A1/GCD(A1,A2), k * A2/GCD(A1,A2))k的{​​{1}}点。

答案 1 :(得分:0)

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

  1. 狙击手位于(0,0),目标位于(3,3)。很明显,子弹的轨迹将触及2个细胞 备注:当狙击手和目标位于线x = y上或与其平行时,触摸的单元格比纵坐标(或横坐标)小1。 (这等于子弹行进距离的xy分量的总和,并减去距离的xy分量的GCD子弹旅行。)
  2. 狙击手位于(0,0),目标位于(0,3)(3,0)。通过观察图片,很明显,子弹的轨迹将触及0个细胞 备注:当狙击手和目标位于xy或平行于xy时,触及的单元格为{{1} }}。 (这等于子弹行进距离的0x分量的总和,并减去距离的yx分量的GCD子弹旅行。)
  3. 狙击手位于y,目标位于(1,1)。很明显,子弹的轨迹将触及(4,3)个细胞 备注:在所有其他情况下,单元格的数量等于子弹行进距离的4x分量的总和,并减去{{的GCD子弹行进距离的1}}和y分量。