大致题意:10个小孩,每个人都有一个序号(从0-9),他们依次围成一圈,然后从0序号的小孩开始报数,从0-3,数到3的人出局,一直循环,问剩下的人是谁,序号是多少???
单纯的只使用数组解决,,,
using System;
namespace 约瑟夫环数组求解
{
class Program
{
static void Main(string[] args)
{
YueSeFuHuan(10,4);
Console.ReadKey();
}
/// <summary>
/// 约瑟夫环问题求解方法
/// </summary>
/// <param name="sum">总人数</param>
/// <param name="num">第几个人出局</param>
static void YueSeFuHuan(int sum,int num)
{
int[] arr = new int[sum];
for (int i = 0; i < sum; i++)
{
arr[i] = 1;
}
int count = 0; //计数器
int arrlength = arr.Length; //剩余人数
while (arrlength > 1)
{
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] == 1)
{
count++;
if (count == num) //如果是规定(第几个人出局)
{
arr[i] = 0; //第i个人出局
arrlength--;
count = 0;
Console.WriteLine("第{0}个人出局,编号是{1}", i+1,i);
}
}
}
}
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] == 1)
{
Console.WriteLine("第{0}个人留下,编号是{1}",i+1,i);
}
}
}
}
}
使用递归解决,,,
假设下标从0开始,0,1,2 … m-1共m个人,从1开始报数,报到k则此人从环出退出,问最后剩下的一个人的编号是多少?
现在假设m=10
0 1 2 3 4 5 6 7 8 9 k=3
第一个人出列后的序列为:
0 1 3 4 5 6 7 8 9
即:
3 4 5 6 7 8 9 0 1(*)
我们把该式转化为:
0 1 2 3 4 5 6 7 8 (**)
则你会发现: ((**)+3)%10则转化为(*)式了
也就是说,我们求出9个人中第9次出环的编号,最后进行上面的转换就能得到10个人第10次出环的编号了
设f(m,k,i)为m个人的环,报数为k,第i个人出环的编号,则f(10,3,10)是我们要的结果
当i=1时, f(m,k,i) = (m+k-1)%m
当i!=1时, f(m,k,i)= ( f(m-1,k,i-1)+k )%m
using System;
namespace 约瑟夫环问题递归
{
class Program
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("请输入数字m,k");
int m = int.Parse(Console.ReadLine());
int k = int.Parse(Console.ReadLine());
for (int i = 1; i <= 10; i++)
{
Console.WriteLine( "第{0}人出局:",YueSeFuHuan(m,k,i)+1);
}
Console.ReadKey();
}
/// <summary>
/// 约瑟夫环问题
/// </summary>
/// <param name="m">总人数</param>
/// <param name="k">第几个人出局</param>
/// <param name="i">出局的次数</param>
/// <returns></returns>
public static int YueSeFuHuan(int m, int k, int i)
{
if (i == 1)
{
return (m + k - 1) % m;
}
else
{
return (YueSeFuHuan(m - 1, k, i - 1) + k) % m;
}
}
}
}