[jobdu]孩子们的游戏(圆圈中最后剩下的数)
2013-08-31 00:44
351 查看
这道题就是典型的约瑟夫环问题。/article/1361752.html 一开始想了一下用数组来做,就是模拟方法,同时记录一下是不是一个节点已经删除。然后看了一下,也很自然的可以用链表来做。但这样的复杂度都是O(m*n)。
如果不用模拟出其中的所有步骤,那么可以用数学方法来解,就是一个递推公式。f(n) = (f(n-1) + m) % n; f(1) = 1。
推导过程参加链接。但精华部分是,当n个数字删掉一个数后,就成为了n-1个数,假设知道n-1个数的剩下的编号x,就可以映射回原来n个数里面。“胜利者的编号为 (x + k) % n。其中k等于m % n。代入(x + k) % n <=> (x + (m % n))%n <=> (x%n + (m%n)%n)%n <=> (x%n+m%n)%n <=> (x+m)%n” 注意里面m%n%n = m%n。
本来想把ans初始化为1的,但是算了一下不对。归根结底是%以后,结果是0到i-1;那么从0计数是最合理的,否则递推公式要全变。
如果不用模拟出其中的所有步骤,那么可以用数学方法来解,就是一个递推公式。f(n) = (f(n-1) + m) % n; f(1) = 1。
推导过程参加链接。但精华部分是,当n个数字删掉一个数后,就成为了n-1个数,假设知道n-1个数的剩下的编号x,就可以映射回原来n个数里面。“胜利者的编号为 (x + k) % n。其中k等于m % n。代入(x + k) % n <=> (x + (m % n))%n <=> (x%n + (m%n)%n)%n <=> (x%n+m%n)%n <=> (x+m)%n” 注意里面m%n%n = m%n。
#include <iostream> using namespace std; int main() { int n; while (cin >> n) { if (n == 0) break; int m; cin >> m; int ans = 0; for (int i = 2; i <=n ; i++) { ans = (ans + m) % i; } cout << ans + 1<< endl; } }
本来想把ans初始化为1的,但是算了一下不对。归根结底是%以后,结果是0到i-1;那么从0计数是最合理的,否则递推公式要全变。
相关文章推荐
- 剑指offer--孩子们的游戏(圆圈中最后剩下的数)
- 孩子们的游戏(圆圈中最后剩下的数)
- 孩子们的游戏(圆圈中最后剩下的数)
- 剑指Offer: 孩子们的游戏(圆圈中最后剩下的数)
- 剑指Offer - 九度1356 - 孩子们的游戏(圆圈中最后剩下的数)
- 约瑟夫环——孩子们的游戏(圆圈中最后剩下的数)
- 剑指offer:孩子们的游戏(圆圈中最后剩下的数)
- 孩子们的游戏(圆圈中最后剩下的数)
- 牛客:剑指offer:孩子们的游戏(圆圈中最后剩下的数) (Java)
- 剑指offer——45.孩子们的游戏(圆圈中最后剩下的数)
- 孩子们的游戏(圆圈中最后剩下的数)
- 剑指offer-孩子们的游戏(圆圈中最后剩下的数)
- 孩子们的游戏(圆圈中最后剩下的数)(java版)
- 九度 题目1356:孩子们的游戏(圆圈中最后剩下的数)
- 约瑟夫环 (孩子们的游戏(圆圈中最后剩下的数))
- 剑指offer — 孩子们的游戏(圆圈中最后剩下的数)约瑟夫环问题
- 剑指Offer--045-孩子们的游戏(圆圈中最后剩下的数)--约瑟夫环
- 九度OJ 1356:孩子们的游戏(圆圈中最后剩下的数) (约瑟夫环)
- 孩子们的游戏(圆圈中最后剩下的数)
- 剑指offer47题(孩子们的游戏:圆圈中最后剩下的数字)