约瑟夫问题的C#解决办法

自己在学数据结构的时候遇到约瑟夫的问题,编写的一段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; }

    }


    class Program
    {
        //用于储存存活的成员的集合
        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);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_33575542/article/details/80303633