每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。
当一个数字删除后,从被删除数字的下一个继续删除第m个数字。
求出在这个圆圈中剩下的最后一个数字。
--------------------------------
约瑟夫环是一个数学的应用问题:已知n小伙伴(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人只剩最后一个小伙伴。。找出这个小伙伴把!
(1)方法一
当然是直接模拟这个过程:可以利用一个链表(环形)来模拟,也可以直接用数组,记得%n就好了
//============================================================================
// Name : YSFCircle.cpp
// Author : YLF
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
using namespace std;
void Solution1(int *arr, int length, int m);
int main() {
int arr[10] = {0,1,2,3,4,5,6,7,8,9};
int m = 5;
Solution1(arr,10,m);
return 0;
}
/*
* simulate the process
*/
void Solution1(int *arr, int length, int m){
int i = 0;
int index = length;
int mIndex = m;
while(index>1){
mIndex = m;
while(mIndex > 0){
if(arr[i] != -1){
mIndex--;
if(mIndex == 0)
arr[i] = -1;
}
i = (i+1)%length;
}
index--;
}
for(i=0;i<length;i++)
if(arr[i] != -1)
cout<<arr[i];
}
(2)约瑟夫算法
约瑟夫这个算法确实很巧妙!
看了好几篇文章,都觉得抄得太high了,着实让智商不够的我纠结了一阵子。。
其实这里就是一个回溯的感觉
假设我们现在要先找到n个元素里第m个 那么就是a[m-1]这个元素被删除了,然后数组变换如下:
0 1 ... m-2 m-1 m ... n-1
0 1 ... m-2 m m+1 ... n -1
我们接下来是从arr[m] 这个元素开始了,如果我们重新把这个新数组看成一个新数组,那么可以表示如下
m m+1 ... n-1 0 1 ... m-2 数组一
如果依然从0开始标记:(对应上面这个数组)
0 1 .... n-m-1 n-m n-m+1 n-2 数组二
我们发现,如果这时候数组二和数组一是一一对应的,如例如数组二的 第n-m+1元素就是数组一的 1元素所以如果数组二的元素位置记为x,在数组一的元素位置记为x'
则有数组二-----》数组一关系 x' = (x+m)%n
那同理,数组三 ---->数组二 就有 x' = (x+m)%(n-1)
所以,如果我们知道了最后一个数组(也就是只剩最后一个元素,他的位置标记当然是0 了 ,一个元素的数组下标就是0),就可以推出剩下两个元素里该元素的位置。。。。以此类推,就可以得到最后剩下那个元素在初始数组里的位置了。。。
确实不好解释,大家想想,就是假设我知道了,最后剩下的那个元素,也就是最后剩下的数组,这个数组我们重新排序了,那这个元素在这个数组的下标肯定是0,好了,我们可以通过这个数组推出该元素在上一个数组(含有两个元素)的坐标,然后再推出上上个数组里的坐标。。。。。
_______________________|
0 if i==1 |
f(i) ={ |
(f(i-1)+m)%i if i>1 |
----------------------------------------|
/*
* using YSF Algorithm
*/
void Solution2(int *arr, int length, int m){
int last = YSF(length,m);
cout<<arr[last];
}
int YSF(int i , int m){
if(i == 1)
return 0;
return (YSF(i-1, m)+m)%i;
}
本文介绍了约瑟夫环问题及其解决方案。通过模拟过程或使用约瑟夫算法,解决从n个编号的小伙伴中,按照特定规则删除元素,最终剩下最后一个小伙伴的问题。文章详细阐述了约瑟夫算法的原理,通过递归方式找出最后剩余的数字在初始序列中的位置。
形成一个圆圈)&spm=1001.2101.3001.5002&articleId=12836319&d=1&t=3&u=a7c18804b1034c298d07a9eef6707dd2)
4508

被折叠的 条评论
为什么被折叠?



