在给定约束的n个同事中选择m个朋友。(编码问题)

时间:2014-12-12 06:47:57

标签: c++ algorithm

杰克在他的办公室里有n名同事和m朋友。杰克为他的m朋友带来了一份礼物。 知道了之后,他所有的n同事都要求他送礼物。 但杰克只想给他的朋友送礼物。 所以,他告诉他们围着他站成一圈,第一位同事在那里 站在n旁边。然后杰克将按照策略进行分发 礼物。他将首先向某人b赠送礼物,并将继续 给每个s人送礼物。有人收到礼物后,他没有 离开圈子。 杰克注意到他朋友的立场,现在他想选择bs以这种方式,只有他和他的所有朋友都能得到这些礼物。

输入格式: 第一行输入包含2个空格分隔的整数,n和m, 杰克的同事人数和杰克的朋友人数。下一行 包含m个空格分隔的整数,杰克的朋友的位置。

输出格式: 输出合适的b和s来执行Jack的计划。如果没有合适的答案 存在,输出“不可能”(没有引号)。 如果有多个解决方案,请打印其中任何一个。 约束:

1<=n<=10^9
1<=m<=10^6

m<=n
杰克的朋友的位置将按顺序递增。 样本输入

  

5 3
    3 4 5

示例输出

  

3 1

2 个答案:

答案 0 :(得分:2)

您可以计算相邻朋友之间的所有差异 复杂性:O(m)

然后观察计算值:

  1. 如果所有差异都相同,那么您可以从第一个朋友开始。
  2. 如果只有一个差异不匹配,那么你可以从不匹配的位置开始。
  3. 示例:

    1 5 13 17
    diff - 4(1st-2nd) 8(2nd-3rd) 4(3rd-4th) 4(4th-1st)
    

    第二个差异中的一个不匹配。你知道第二个差异是第二和第三个朋友之间的距离。所以你可以从第三个朋友开始

    1. 否则就不可能

答案 1 :(得分:1)

执行前跳和后跳可能是一种解决方案。如果小于或等于两个朋友,则结果为真。如果有两个以上的朋友,请应用以下解决方案。

<强> 1。选择第一个人并创建前跳间隙列表。

例如,n=19, friends = 1 2 3 11 12 13。前跳间隙列表为[1,2,10,11,12]

<强> 2。从我们选择的人开始,对于差距列表中的每个差距

A)创建一个跳跃索引,如果跳跃覆盖它,则保持列表中朋友的状态。

B)开始前跳差距。 Jumping value = Current position + gap。如果jumping value > njumping value = jumping value - n。重复跳跃,直到跳跃指数覆盖所有朋友或跳跃位置不适合朋友。

例如,我们选择人1和差距1.显然,人1被覆盖。标记人1的跳跃指数到覆盖。然后跳到人2(1 + 1)。现货这个朋友的位置存在。标记人2的跳跃指数。

C)如果某个朋友没有被2(B)覆盖,那么从我们选择的人那里用我们选择的差距进行向后跳跃。 Jumping value = Current position - gap。如果jumping value < 1 (starting point)jumping value = jumping value + n。重复向后跳跃,直到跳跃指数覆盖所有朋友或跳跃位置不适合朋友。

例如,与人1和差距1.我们试图找人0(1-1)。 0小于1,所以用0 + 19 = 19进行调整。人19不存在,我们在这里结束这个差距。

D)检查这个差距是否涵盖所有朋友。如果为true,则通过向后跳跃找到b,将人返回b,将间距返回为s。如果不是,请检查下一个间隙并执行2(B)和2(C)。

第3。从我们选择的人开始,执行向后跳跃

同样地,我们正在完成整个过程,如步骤1和步骤2,但我们不是向前移动,而是向后移动。

  • 首先,在我们选择的人的朋友位置n +朋友位置创建一个向后跳跃列表。列表中的朋友位置。

例如,n=19, friends = 1 2 3 11 12 13。向后跳跃间隙列表为[7,8,9,17,18]

  • 然后执行向后跳转。与前跳不同,我们先做后仰。这意味着在所有向后跳跃的差距上执行2(A) ->2(C) -> 2(B) -> 2(D)

    <强> 4。没有解决方案

    如果第2步和第3步都不能涵盖所有朋友,则根本没有解决方案。


解决方案分析

首先,[1,n]中的b和([1,n-1]和[ - (n-1), - 1]中的s)。 s可以是积极的移动

假设有一个解决方案,那么就存在人b,然后是人b + s,人b + 2s,......人b +(m-1)s。

从列表中挑选任何朋友有三种可能性:

  • 名单上的人(人b)
  • 列表中间的人(人物b + rs,[1,m-2]中的r)
  • 名单末尾的人(人b +(m-1)s)

如果被选中的人是名单上的人,则可以通过2(A)/(3)过程中的一个来解决。

如果被选中的人是列表中间的人,则可以通过2(A)+2(B)过程中的一个来解决。

如果被选中的人是列表末尾的人,则可以通过(3)过程中的一个来解决。

如果不按上述方法处理,则表示无解决方案。

相关问题