约瑟夫环:
已知n个人(以编号1,2,3,4....n分别表示)围坐在一张圆桌周围。从编号为k开始报数,数到m的那个人出列;他的下一个人又从一开始报数,数到m的那个人又出列;依次规律重复下去,直到圆桌周围的人全部出列。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int[] intPers = Jose(5, 2, 3); //调用自定义方法解决约瑟夫环问题
Console.WriteLine("出列顺序:");
for (int i = 0; i < intPers.Length; i++)
{
Console.Write(intPers[i] + " "); //输出出列顺序
}
int[] intArray = new int[2];
intArray[0] = 1;
intArray[1] = 1;
Console.ReadLine();
}
#region 约瑟夫环问题算法
/// <summary>
/// 约瑟夫环问题算法
/// </summary>
/// <param name="total">总人数</param>
/// <param name="start">开始报数的人编号</param>
/// <param name="alter">要出列的人报的数</param>
/// <returns>返回一个int类型的一维数组</returns>
static int[] Jose(int total, int start, int alter)
{
int j, k = 0;
//intCounts数组存储按出列顺序的数据,以当结果返回
int[] intCounts = new int[total];
//intPers数组存储初始数据 -----------即人的序号(0~total-1)
int[] intPers = new int[total + 1]; //备注,这里由于
//对数组intPers赋初值,第一个人序号为1,第二人为2,依此下去
for (int i = 1; i < total + 1; i++)
{
intPers[i] = i;
}
//按出列次序依次存于数组intCounts中
for (int i = total; i >= 2; i--)
{
//找出新的开始报数人员编号
start = (start + alter - 1) % i;
//将需出列的人员编号,存放进最终返回的intCount数组
intCounts[k] = intPers[start];
//每出列一个,最终结果intCount的下标需加一记录,最终intCount[]数组的结果就能按照出列顺序输出
k++;
//这里有一个人出列后,需要给intPers[start+1]~intPers[total]的元素重新赋值
for (j = start + 1; j <= i; j++)
{
intPers[j - 1] = intPers[j];
}
}
//前面循环输出数组的时候,保留了俩个数。
//剩下的intPers[0]为初始赋值即0,intPers[1]为最后剩下的人员编号,。
intCounts[k] = intPers[1];
//结果返回
return intCounts;
//备注:若Jose(5, 2, 3),则最终:
//intCounts:4,2,1,3,5
//intPers:0,5,5,5,5,5 ***第一个元素为0是因为新建int数组的元素默认值
//备注:若Jose(1, 1, 1),则最终:
//intCounts:1
//intPers:0,1 ***第一个元素为0是因为新建int数组的元素默认值
}
#endregion
}
}
运行结果: