约瑟夫环C#解决方法
/*约瑟夫环
(问题描述)
约瑟夫问题的一种描述是:编号为1,2,......n,的n个人按顺时针方向围坐一圈,每个人持有一个密码(正整数)。一开始任意选
一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新
的m值,从他在顺时针方向下一个人开始从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。
(基本要求)
利用单向循环链表存储结构模拟此过程,按照出列顺序印出个人的编号。
(测试数据)
m的初值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4,首先m为6(正确的出列顺序应为6,1,4,7,2,3,5)。
下面是我的解决方法:
根据问题所描述的,这是个环问题,我们可以先模拟一个环.
声明:我这里是用双向链表的,虽然对这个问题没太大意义,但我还是保留为双向的,因为我在考虑这个问题可以衍生出很多其它问题来,只为我自己所用而以。呵呵……为了性能,而且只是解决这一个问题,你可以改成单向链表。
public class Circle private int id; public Node PreNode public Node NextNode { public int ID public uint Password public int Count public Circle() public void Add(int id,uint password) this.Add(node); public void Add(int id) private void Add(Node node) firstNode = node; lastNode.NextNode = firstNode; firstNode.NextNode = lastNode; node.PreNode = lastNode; firstNode.PreNode = node; public Node NextNode() public void RemoveNode(Node node) //pre node;current node;next node |
2。根据问题加载数据
List<Circle.Node> outList = new List<Circle.Node>(); int index = 0; int n = 7; uint m = 20; List<Circle.Node> nodeList = new List<Circle.Node>(); nd = new Circle.Node(); nd = new Circle.Node(); nd = new Circle.Node(); nd = new Circle.Node(); nd = new Circle.Node(); nd = new Circle.Node(); Circle c = new Circle(); |
3.根据问题事件开始起动
while (c.Count > 0) { index++; nd = c.NextNode(); if (index == m) { c.RemoveNode(nd); outList.Add(nd); index = 0; m = nd.Password; } } |
4.显示结果
foreach (Circle.Node node in outList) { Console.WriteLine(node.ID); } |
完整源代码:
using System; using System.Collections.Generic; using System.Text;namespace Arithmetic { class Program { static void Main(string[] args) { List<Circle.Node> outList = new List<Circle.Node>(); int index = 0; int n = 7; uint m = 20; List<Circle.Node> nodeList = new List<Circle.Node>(); Circle.Node nd = new Circle.Node(); nd.ID = 1; nd.Password = 3; nodeList.Add(nd); nd = new Circle.Node(); nd.ID = 2; nd.Password = 1; nodeList.Add(nd); nd = new Circle.Node(); nd.ID = 3; nd.Password = 7; nodeList.Add(nd); nd = new Circle.Node(); nd.ID = 4; nd.Password = 2; nodeList.Add(nd); nd = new Circle.Node(); nd.ID = 5; nd.Password = 4; nodeList.Add(nd); nd = new Circle.Node(); nd.ID = 6; nd.Password = 8; nodeList.Add(nd); nd = new Circle.Node(); nd.ID = 7; nd.Password = 4; nodeList.Add(nd); Circle c = new Circle(); foreach (Circle.Node node in nodeList) { c.Add(node.ID, node.Password); } while (c.Count > 0) { index++; nd = c.NextNode(); if (index == m) { c.RemoveNode(nd); outList.Add(nd); index = 0; m = nd.Password; } } foreach (Circle.Node node in outList) { Console.WriteLine(node.ID); } Console.Read(); } } public class Circle { public class Node { private Node preNode; private Node nextNode; private int id; private uint password; public Node PreNode { get { return preNode; } set { preNode = value; } } public Node NextNode { get { return nextNode; } set { nextNode = value; } } public int ID { get { return id; } set { id = value; } } public uint Password { get { return password; } set { password = value; } } } private Node firstNode = null; private Node lastNode=null; private Node nextNode = null; private int count = 0; public int Count { get { return count; } set { count = value; } } public Circle() { } public void Add(int id,uint password) { count++; Node node = new Node(); node.ID = id; node.Password = password; this.Add(node); } public void Add(int id) { count++; Node node = new Node(); node.ID = id; this.Add(node); } private void Add(Node node) { if (firstNode == null) { firstNode = node; lastNode = firstNode; lastNode.NextNode = firstNode; lastNode.PreNode = firstNode; firstNode.NextNode = lastNode; firstNode.PreNode = lastNode; } else { lastNode.NextNode = node; node.PreNode = lastNode; node.NextNode = firstNode; firstNode.PreNode = node; lastNode = node; } } public Node NextNode() { Node node=new Node(); if (nextNode == null) { node = firstNode; nextNode = firstNode.NextNode; } else { node = nextNode; nextNode = node.NextNode; } return node; } public void RemoveNode(Node node) { count--; Node _preNode = node.PreNode; Node _nextNode = node.NextNode; _preNode.NextNode = _nextNode; _nextNode.PreNode = _preNode; } //pre node;current node;next node //first node-pre->last node } } |
总结:当碰到问题时,思路理清。程序只不过是解决问题的工具,当你分析到问题本质,还原问题真相,有时会给你海阔天空的感觉。不要一味的去为写代码而写代码,写代码是为了解决问题,呵呵……
用“面向对象”来思考问题,解决问题,把问题分层,分块,这样你的思路就清晰得多。
以上代码只是做为参考,如果你有兴趣,可以写得更完善一些。
约瑟夫环C#解决方法的更多相关文章
- php解决约瑟夫环
今天偶遇一道算法题 "约瑟夫环"是一个数学的应用问题:一群猴子排成一圈,按1,2,-,n依次编号.然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数, 再数到第m只,在把 ...
- poj 3517 约瑟夫环
最简单的约瑟夫环,虽然感觉永远不会考约瑟夫环,但数学正好刷到这部分,跳过去的话很难过 直接粘别人分析了 约瑟夫问题: 用数学方法解的时候需要注意应当从0开始编号,因为取余会等到0解. 实质是一个递推, ...
- 用pl/sql游标实现约瑟夫环
什么是约瑟夫环: 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为1的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数, ...
- 通过例子进阶学习C++(七)CMake项目通过模板库实现约瑟夫环
本文是通过例子学习C++的第七篇,通过这个例子可以快速入门c++相关的语法. 1.问题描述 回顾一下约瑟夫环问题:n 个人围坐在一个圆桌周围,现在从第 s 个人开始报数,数到第 m 个人,让他出局:然 ...
- Java实现约瑟夫环
什么是约瑟夫环呢? 约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个 ...
- C++ 约瑟夫环
约瑟夫环: 已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,直到圆桌周 ...
- 51nod 1073 约瑟夫环
题目链接 先说一下什么是约瑟夫环,转自:传送门 关于约瑟夫环问题,无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂度高达O(nm),当n,m非常大( ...
- POJ-2886 Who Gets the Most Candies?---线段树+约瑟夫环
题目链接: https://cn.vjudge.net/problem/POJ-2886 题目大意: N个人围成一圈第一个人跳出圈后会告诉你下一个谁跳出来跳出来的人(如果他手上拿的数为正数,从他左边数 ...
- "递归"实现"约瑟夫环","汉诺塔"
一:约瑟夫环问题是由古罗马的史学家约瑟夫提出的,问题描述为:编号为1,2,-.n的n个人按顺时针方向围坐在一张圆桌周围,每个人持有一个密码(正整数),一开始任选一个正整数作为报数上限值m,从第一个人开 ...
随机推荐
- SQL Server Compact/SQLite Toolbox 使用
最近一个嵌入式的数据库用的SqlCe 需要导入到Sqlite, 网上查到了这个工具--SQL Server Compact/SQLite Toolbox.但是在使用的时候遇到了一点小曲折,记录下来给需 ...
- 服务器cpu100%问题分析
ecs 130 : slb:
- win10 uwp DataContext
本文告诉大家DataContext的多种绑法. 适合于WPF的绑定和UWP的绑定. 我告诉大家很多个方法,所有的方法都有自己的优点和缺点,可以依靠自己喜欢的用法使用.当然,可以在新手面前秀下,一个页面 ...
- CSS组件
下拉菜单 .dropdown:将下拉菜单触发器和下拉菜单包含在其中 .dropdown-menu:给<ul>制定下拉菜单的样式 .dropup:向上弹出菜单 .dropdown-menu- ...
- 【计算机网络】应用层(一) HTTP
HTTP报文 HTTP报文是HTTP应用程序间发送的数据块,它由三部分组成:起始行(start line),首部(header)和主体(body),如下图所示: 从分类上,报文又可以分为请求报 ...
- HTTP 简要
HTTP协议就是客户端和服务器交互的一种通迅的格式. 当在浏览器中点击这个链接的时候,浏览器会向服务器发送一段文本,告诉服务器请求打开的是哪一个网页.服务器收到请求后,就返回一段文本给浏览器,浏览器会 ...
- LINUX 笔记-Shell 脚本控制语句
1.if 语句 if condition1;then command1 elif condition2;then command2 else command3 fi 2.case 语句 case va ...
- javascript 之作用域-06
作用域 作用域是指变量和函数可访问范围,他规定了如何查找变量,也就是确定当前执行代码对变量的访问权限. 作用域有两种工作模式: 静态作用域 :又称为词法作用域,在编译阶就可以决定变量的引用,由程序定义 ...
- N厂水鬼烂大街?那来看ZF厂V4帝舵小红花
自从帝舵小红花推上市面之后,各大工厂都在推出新版本,但做得最成熟的还是ZF厂,帝舵这个品牌是非常低调的,很少有人关注,但是ZF厂在这款腕表也是下了不少功夫,曾经帝舵小红花和N厂水鬼并列为最顶级的表畅销 ...
- [译]ASP.NET Core 2.0 网址重定向
问题 如何在ASP.NET Core 2.0中实现网址重定向? 答案 新建一个空项目,在Startup.cs文件中,配置RewriteOptions参数并添加网址重定向中间件(UseRewriter) ...