【问题标题】:N number of smileys using minimum keystrokes使用最少击键次数的 N 个笑脸
【发布时间】:2015-08-30 02:27:35
【问题描述】:

这是一个面试问题,我自己无法解决。谁能给她点灯?

问题:假设您有聊天客户端,在文本框中您有一个笑脸(它已经存在)。现在你想要那个笑脸 N 次,并且只允许复制和粘贴两个操作。结果必须是 N 个笑脸,不多不少。复制基本上是^a + ^c。您总是必须在给定时间复制文本框中的所有笑脸。复制是一键,粘贴是一键。为这个问题写一个算法/程序。复杂度会是多少?

【问题讨论】:

  • 类似于Maximum number of characters using keystrokes A, Ctrl+A, Ctrl+C and Ctrl+V。也许你可以应用那里的一些逻辑来在这里做出努力。
  • 更正式地说,是否准确地说我们以result = ":)"; clipboard = ""; 开头,复制为clipboard = result;,粘贴为result += clipboard;
  • @KenWhite 这些问题表面上很相似,但解决技术与在相似状态空间上的动态规划没有太多共同点。
  • @David:是的,我知道它们只是相似的,这就是为什么我没有投票关闭作为重复。解决它们的思维过程是相似的(虽然不一样,很明显)IMO。 (这绝对是一个更好的起点,而不是在这里发布问题并等待其他人为您解答。)
  • @DavidEisenstat:是的。

标签: algorithm


【解决方案1】:

无论笑脸 N 的数量是多少,将 N 分解为素数的乘积。然后对于分解中的每个素数 p,您需要进行一次复制和 p-1 粘贴。如果“复制”意味着您必须复制整个笑脸字符串,则这是可能的最少操作数。操作的总数是N的因式分解中所有素因子的总和。

【讨论】:

    【解决方案2】:

    user2566092's answer是正确的,但是声明

    这是可能的最少操作数

    声称没有证据。这是一个正式的理由。

    设 n 为目标笑脸数。配置 (r, k) 由结果中的笑脸数量 r 和剪贴板上的笑脸数量 k 组成。初始配置为 (1, 0)。从 (r, k) 开始,一键即可访问配置 (r, r) [copy] 和 (r + k, k) [paste]。

    下面的引理意味着,在复制之后,结果中的笑脸数量除以 n。

    引理假设 g 除以 r 和 k(g|r 和 g|k)。从 (r, k) 可达的每个配置 (r', k') 都满足 g|r' 和 g|k'。

    证明归纳法。如果下一步是复制,到 (r, r),然后 g|r 和 g|r。如果下一步是粘贴,到(r + k, k),然后g|r + k和g|k。

    现在我们可以证明主要主张了。

    定理 从 (1, 0) 到某个 (n, k)(其中 k 是任意的)的最小步数是 p1 + p2 + ... + pm,其中 n = p1 p2 。 .. pm 是质因数分解。

    证明 user2566092 覆盖了上限:对于从 1 到 m 的 i,复制一次并粘贴 pi - 1 次。当 n = 1 时,下限很明显。否则,最好的第一个动作显然是复制到 (1, 1)。我们通过归纳证明从 (1, 1) 到 (n, k) 的最小步数是 p1 + p2 + ... + pm - 1。

    根据引理,从 (1, 1) 开始,我们所能做的就是粘贴直到 r 除以 n。修复特定的 r|n。从 (r, r) 到 (n, n) 以及从 (1, 1) 到 (n/r, n/r) 的最佳动作序列显然是相同的。通过置换素数不失一般性,假设 r = p1 p2 ... pj。由于 a b >= a + b 对于 a,b >= 2,我们有 r >= p1 + p2 + ... + pj。如果 r = p1 + p2 + ... + pj - 1。如果r = n,则总成本为 n - 1 >= p1 + p2 + ... + pm - 1。

    【讨论】:

    • 你是对的,我应该给出一个证明,因为正如你的论述所示,证明有点冗长。 +1 完全覆盖它。 =)
    【解决方案3】:

    2 * 2log(N)。 每次都复制所有内容,直到您不再需要完整的集合。然后你可以只复制列表的一部分。

    例如7 个笑脸:

    1 复制所有内容

    2 复制所有内容

    4 只复制 3

    有 7 个。

    【讨论】:

    • 这不是在最少的操作中建立最多数量的笑脸的最佳方式。考虑是否有 6 个操作。您的方法将加倍 3 次,给出 8 个笑脸并使用 6 个操作。但是,如果您复制-粘贴-粘贴,然后再次复制-粘贴-粘贴,您仍然使用 6 次操作,但您会得到 9 个笑脸。
    • 复杂度是一个上限:)
    【解决方案4】:

    针对上述问题的程序如下。在最坏的情况下,该解决方案的时间复杂度为 O(n)。最坏的情况发生在给定数是素数时。

    #include <iostream>
    using namespace std;
    int main()
    {
        int smiles;
        cin>>smiles;
        int ans=0; 
        for(int i=2;i<=smiles;i++)
        { 
            while(smiles%i==0)
            { 
                ans+=i; 
                smiles/=i; 
            } 
        } 
        cout<<ans<<"\n";
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多