标签:style blog http color os ar for div sp
约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌剩下最后一个人,求这个人的编号。
这是一个经典的算法题,拿到手上,先想到的是模拟报数过程,实现如下(是在cocos2dx环境下,代码中的ccarray可以换成c数组):
int josephus(int n, int m, int k) { CCArray *array = CCArray::create(); for (int i = 0; i < n; i ++) { array->addObject(CXNumber::create(i + 1)); } int index = k - 1; while (true) { for (int i = 0; i < m; i ++) { if (array->count() == 1) { return ((CXNumber *) array->objectAtIndex(0))->getIntValue(); } if (i == m - 1) { bool changeIndex = (index == array->count() - 1); array->removeObjectAtIndex(index); if (changeIndex) { index = 0; } } else { index ++; if (index == array->count()) { index = 0; } } } } }
后来网上搜了一下,看到一个 http://blog.csdn.net/dengyaolongacmblog/article/details/39208675 的实现,恍然大悟,又写了个基于数学归纳的实现,复杂度大大降低,从O(m^n)到O(n), 实现如下:
int anotherJosephus(int n, int m, int k) { CCArray *array = CCArray::create(); for (int i = 0; i < n; i ++) { array->addObject(CXNumber::create(i + 1)); } int index = k - 1; for (int i = 0; i < n - 1; i ++) { index = (index + m) % array->count(); //数学归纳得出要被淘汰的index index --; if (index < 0) { index = array->count() - 1; } array->removeObjectAtIndex(index); } return ((CXNumber *) array->objectAtIndex(0))->getIntValue(); }
以上两种代码,都已测试过
如有问题,欢迎指正
标签:style blog http color os ar for div sp
原文地址:http://www.cnblogs.com/tjuzjf/p/3986392.html