自己在学数据结构的时候遇到约瑟夫的问题,编写的一段C#代码用于解决该问题,时间复杂度为O(N),如果有做的不好的地方希望大家评论区提出,我一定好好学习并且进行修改,谢谢。
/// <summary>
/// 问题描述:约瑟夫是犹太军队的一个将军,在反抗罗马的起义中,他所率领的军队被击溃,只剩下残余的部队40余人,
/// 他们都是宁死不屈的人,所以不愿投降做叛徒。一群人表决说要死,所以用一种策略来先后杀死所有人。
/// 于是约瑟夫建议:每次由其他两人一起杀死一个人,而被杀的人的先后顺序是由抽签决定的,约瑟夫有预谋地抽到了最后一签,
/// 在杀了除了他和剩余那个人之外的最后一人,他劝服了另外一个没死的人投降了罗马。
/// 规则定义:
/// 在一间房间总共有n个人(下标0~n-1),只能有最后一个人活命。
/// 按照如下规则去杀人:
/// 所有人围成一圈,顺时针报数,每次报到q的人将被杀掉,被杀掉的人将从房间内被移走,然后从被杀掉的下一个人重新报数,
/// 继续报q,再清除,直到剩余一人。
/// 你要做的是:当你在这一群人之间时,你必须选择一个位置以使得你变成那剩余的最后一人,也就是活下来。
/// </summary>
///
using System;
using System.Collections.Generic;
using System.Linq;
namespace TXYueSeFuTest
{
public class Person
{
public int pos; //表示该人在队伍中的位置,拍的序号
private string name; //这个人的姓名
public string Name { get => name; set => name = value; }
}
{
//用于储存存活的成员的集合
private static List<Person> person = new List<Person>();
static void Main(string[] args)
{
int num, pos, s = 0;
string inputStr = Console.ReadLine().Trim();
num = int.Parse(inputStr.Split(' ')[0]);
pos = int.Parse(inputStr.Split(' ')[1]);
Program test = new Program();
InitList(person, num); //初始化集合
//Display(person); //用于查看集合的数据是否成功插入
test.YueSeFu(num, pos, person); //使用方法对约瑟夫问题进行解决
////通过数学方法对约瑟夫问题进行简化解决,但是只能输出最后存活的一位成员
//for (int i = 2; i <= num; i++)
//{
// s = (s + pos) % i;
// Console.Write(s + "\t");
//}
//Console.Writeline(s + 1);
}
/// <summary>
/// 初始化List集合,设置队伍的人数并把它们排好队
/// </summary>
/// <param name="pL">队伍,把每个人都编号序</param>
/// <param name="num">表示队伍的人数</param>
private static void InitList(List<Person> pL, int num)
{
for (int i = 1; i <= num; i++)
{
Person p = new Person();
p.pos = i;
p.Name = i.ToString();
pL.Add(p);
}
}
/// <summary>
/// 解决约瑟夫问题的方法
/// </summary>
/// <param name="num">存活的人数</param>
/// <param name="pos">隔多少人死一个</param>
/// <param name="pL">存活人的集合</param>
void YueSeFu(int num, int pos, List<Person> pL)
{
int count = pos - 1; //用来计数
while(num >= pos)
{
Console.Write(pL[count].Name + "-->");
pL.Remove(pL[count]);
num--;
count = (count + pos -1) % num;
//Display(pL);
}
for(int i=0;i<pL.Count;i++)
Console.Write(pL[i].Name+"、");
Console.WriteLine();
}
/// <summary>
/// 用于查看集合中数据的情况,
/// </summary>
/// <param name="p">插入的集合</param>
static void Display(List<Person> p)
{
for(int i = 0; i < p.LongCount()-1; i++)
{
Console.Write(p[i].Name+"-->");
}
Console.WriteLine(p[(int)p.LongCount() - 1].Name);
}
}
}