📜  拼图 |两个带降落伞的机器人在一条线上

📅  最后修改于: 2022-05-13 01:57:25.844000             🧑  作者: Mango

拼图 |两个带降落伞的机器人在一条线上


问题
两个机器人带着降落伞降落在无限的一维数轴上。他们都在着陆后立即释放降落伞并开始移动。他们只能使用以下功能。

I. moveLeft() // 机器人在 1 单位时间内向左移动 1 个单位

二、 moveRight() // 机器人在 1 单位时间内向右移动 1 个单位

三、 noOperation() // 机器人不移动,需要 1 个单位时间

四、 onTopOfParachute() // 如果机器人站在任何一个降落伞的顶部,则返回 true,否则返回 false



V. didWeMeet() // 如果机器人遇到另一个机器人,则返回真,否则返回假

编写一个函数,使机器人彼此相遇。机器人将执行此函数的相同副本。

解决方案:
方法一:
将两个机器人向相反方向移动,并在每一步检查它们是否相遇。
但这行不通。考虑机器人 1 在位置 0 和机器人 2 在位置 100。如果机器人 1 向右移动,机器人 2 向左移动,它们将在位置 50 相遇。但如果机器人 1 向左移动而机器人 2 向右移动,他们永远不会见面。因为我们没有任何方法可以找出机器人的坐标。这种方法行不通。

方法二:
向左移动两个机器人。如果机器人穿过降落伞。反转第二个机器人的方向并继续沿相同方向移动第一个机器人。
但这行不通。因为两个机器人都执行各自程序的单独副本。一个程序只能影响执行该程序的机器人,而不能影响另一个机器人,因为它是由同一程序的副本单独执行的。并且它的运动是由那个程序控制的,一个变量分配在另一个程序中将不起作用,即不能从这个机器人执行的程序中改变其他机器人的方向。

方法三:
按照这个模式 moveLeft() 1 次,moveRight() 2 次,moveLeft() 3 次等等。在每次迭代中,机器人都会越过自己的降落伞一次。但是经过一段时间后,一个机器人会越过自己的降落伞,也会越过另一个机器人的降落伞。此时,它已经与另一个机器人相遇了。

方法四:
无论机器人是否已到达其他人的降落伞,请保留一个标志。如果已到达,则调用 moveLeft() 两次,否则调用 moveLeft() 和 noOperation()。这样,一个机器人一到达另一个机器人的降落伞,它的速度就会加倍,最终他们会相遇。
注意:不要从着陆点开始以两倍于其他机器人的速度移动机器人。因为我们没有任何信息哪个机器人在后面,哪个机器人在前面。因此,如果前面的机器人以两倍于落后机器人的速度移动,那么它将永远无法抓住它,因此永远不会相遇。

伪代码:

void roboMeet()
{
  // set flag as false.
  bool reachedParachute = false;

  // Till both robots meet
  while( !didWeMeet() )
  {
    // If flag is set, move left twice.
    if(reachedParachute)
    {
        moveLeft();
        moveLeft();
    }
        
    // Else walk left for 1 unit of time
    // and stop for 1 unit.   
    else
    {
        moveLeft();
        noOperation();
    }
                  
    // If reach on top of parachute, set flag as true.
    if( onTopOfParachute() )
    {
      reachedParachute = true;
    }
  }
}