zoukankan      html  css  js  c++  java
  • Live Archive 3882 And Then There Was One

      【原题链接

      约瑟夫环,普通链表法O(nk)复杂度无法承受,但是可以有O(n)的算法。

      以下摘自百度百科

      无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂度高达O(nm),当n,m非常大(例如上百万,上千万)的时候,几乎是没有办法在短时间内出结果的。我们注意到原问题仅仅是要求出最后的胜利者的序号,而不是要读者模拟整个过程。因此如果要追求效率,就要打破常规,实施一点数学策略。

      为了讨论方便,先把问题稍微改变一下,并不影响原意:

      问题描述:n个人(编号0~(n-1)),从0开始报数,报到m-1的退出,剩下的人继续从0开始报数。求胜利者的编号。

      我们知道第一个人(编号一定是(m-1)%n) 出列之后,剩下的n-1个人组成了一个新的约瑟夫环(以编号为k=m%n的人开始):

      k k+1 k+2 ... n-2,n-1,0,1,2,... k-2

      并且从k开始报0。

      现在我们把他们的编号做一下转换:

      k --> 0

      k+1 --> 1

      k+2 --> 2

      ...

      ...

      k-3 --> n-3

      k-2 --> n-2

      序列1:0,1,2,3 … n-2,n-1

      序列2:0,1,2,3 … k-2,k,…,n-2,n-1

      序列3:k,k+1,k+2,k+3,…,n-2,n-1,1,2,3,…,k-2

      序列4:0,1,2,3 …,5,6,7,8,…,n-3,n-2

      变换后就完完全全成为了(n-1)个人报数的子问题,假如我们知道这个子问题的解:例如x是最终的胜利者,那么根据上面这个表把这个x变回去不刚好就是n个人情况的解吗?!!变回去的公式很简单,相信大家都可以推出来:

      ∵ k=m%n;

      ∴ x' = x+k = x+ m%n ; 而 x+ m%n 可能大于n

      ∴x'= (x+ m%n)%n = (x+m)%n

      得到 x‘=(x+m)%n

      如何知道(n-1)个人报数的问题的解? 对,只要知道(n-2)个人的解就行了。(n-2)个人的解呢?当然是先求(n-3)的情况 ---- 这显然就是一个倒推问题!好了,思路出来了,下面写递推公式:

      令f表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f[n].

      递推公式:

      f[1]=0;

      f[i]=(f[i-1]+m)%i; (i>1)

       

      也就是说,假设最后为第n层,只剩下编号0(人数为1),然后向上推一层,那么(f[i-1] + m) % i就是第n层0编号在第n-1层的位置,再向上推到第一层恢复为原来序列,那么此时推到的位置就是最后的赢家的真实位置了。

      ps:《训练指南》里的代码好像过不了这题。

    View Code
     1 #include <stdio.h>
     2 #include <iostream>
     3 using namespace std;
     4 int main()
     5 {
     6     int n, k, m;
     7     while(cin >> n >> k >> m)
     8     {
     9         if( n==0 && k==0 && m==0 ) break;
    10         int cur = 0;
    11         for(int i = 2; i < n; ++ i)
    12             cur = (cur + k) % i;
    13         cout << (cur + m) % n + 1 << endl;
    14     }
    15     return 0;
    16 }
  • 相关阅读:
    Construct Binary Tree from Preorder and Inorder Traversal
    Construct Binary Tree from Inorder and Postorder Traversal
    Maximum Depth of Binary Tree
    Sharepoint 2013 创建TimeJob 自动发送邮件
    IE8 不能够在Sharepoint平台上在线打开Office文档解决方案
    TFS安装与管理
    局域网通过IP查看对方计算机名,通过计算机名查看对方IP以及查看在线所有电脑IP
    JS 隐藏Sharepoint中List Item View页面的某一个字段
    SharePoint Calculated Column Formulas & Functions
    JS 两个一组数组转二维数组
  • 原文地址:https://www.cnblogs.com/huangfeihome/p/2766327.html
Copyright © 2011-2022 走看看