用C++编程解决约瑟夫环问题
约瑟夫问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环。
人们站在一个等待被处决的圈子里。 计数从圆圈中的指定点开始,并沿指定方向围绕圆圈进行。 在跳过指定数量的人之后,执行下一个人。 对剩下的人重复该过程,从下一个人开始,朝同一方向跳过相同数量的人,直到只剩下一个人,并被释放。
问题即,给定人数、起点、方向和要跳过的数字,选择初始圆圈中的位置以避免被处决。
历史:
这个问题是以弗拉维奥·约瑟夫命名的,它是1世纪的一名犹太历史学家。他在自己的日记中写道,他和他的40个战友被罗马军队包围在洞中。他们讨论是自杀还是被俘,最终决定自杀,并以抽签的方式决定谁杀掉谁。约瑟夫斯和另外一个人是最后两个留下的人。约瑟夫斯说服了那个人,他们将向罗马军队投降,不再自杀。约瑟夫斯把他的存活归因于运气或天意,他不知道是哪一个.
// VS2017 C++ 编译通过, Designed by DGS-SK, Nov. 23, 2024
#include <stdio.h>
#include <string.h>
#include "pch.h"
#include <iostream>
using namespace std;
int Joseph(int n, int m)
{
if (n <= 0 || m <= 0) return -1;
int *arr = new int[n];
if (n == 1)
{
return 0;
}
if (m == 1)
{
return n-1;
}
for (int i = 0; i < n; i++)
{
arr[i] = i;
}
int scnt = n; // survial count
int k = m % scnt;
int startindex = 0;
int killindex = 0;
while (true)
{
if (scnt == 1) return arr[0];
k = m % scnt;
if (startindex + k > scnt)
{
killindex = (startindex + k) % scnt - 1;
}
else
{
killindex = (startindex + k - 1);
}
if (killindex == scnt - 1)
{
startindex = 0;
scnt--;
}
else
{
for (int i = killindex; i < (scnt - 1); i++)
{
arr[killindex] = arr[killindex + 1];
}
scnt--;
startindex = killindex;
}
}
}
int main(void)
{
int n, m;
int survival;
start:
printf("Please input Joseph problem's N and M: ");
scanf_s("%d, %d", &n, &m);
if (n <= 0 || m <= 0)
goto exit1;
survival = Joseph(n, m);
printf("N = %d, M = %d\n", n, m);
printf("The survival people is No. %d \n\n", survival);
goto start;
exit1:
printf("The End");
return 0;
}