"递归"实现"约瑟夫环","汉诺塔"
一:约瑟夫环问题是由古罗马的史学家约瑟夫提出的,问题描述为:编号为1,2,….n的n个人按顺时针方向围坐在一张圆桌周围,每个人持有一个密码(正整数),一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始报数,报到m时停止报数,报m的那个人出列,将他的密码作为新的m值,从他顺时针方向的下一个人开始重新从1报数,数到m的那个人又出列;如此下去,直到圆桌周围的人全部出列为止。
一般情况下,循环链表就可以解决这个问题,但是我正在学习递归,所以就递归实现了,下面附上代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LEN sizeof(struct josepf)
struct josepf
{
int id;
char passwd[20];
struct josepf * next;
};
int joseph(struct josepf *,struct josepf *,int);
int joseph(struct josepf *trans,struct josepf *tail,int passwd1)
{
char passwd[20];
int i;
struct josepf *q,*p,*next,*s;
if(passwd1 == 1) //注意:如果传的密码是1,就表示下一个人直接出
{
s = trans->next;
tail->next = s;
strcpy(passwd,trans->passwd);
printf("第%d个人出列(密码:%s)\n",trans->id,trans->passwd);
free(trans);
if(s->next != s)
{
joseph(s,tail,atoi(passwd));
}
else
printf("第%d个人出列(密码:%s)\n",s->id,s->passwd);
}
else //其他情况都要循环去找
{
for(i = 1,p = trans;i != passwd1;i++,p = p->next)
q = p;
next = p->next;
strcpy(passwd,p->passwd);
q->next = next;
printf("第%d个人出列(密码:%s)\n",p->id,p->passwd);
free(p);
if(next->next != next)
{
joseph(next,q,atoi(passwd));
}
else
printf("第%d个人出列(密码:%s)\n",next->id,next->passwd);
}
}
int main(int argc,char *argv[])
{
struct josepf *p1,*p2,*head,*tail;
int num,firstpasswd;
int i,id = 1;
printf("请输入人数:");
scanf("%d",&num);
printf("请输入初始密码:");
scanf("%d",&firstpasswd);
p1 = (struct josepf *)malloc(LEN);
head = p1;
printf("请输入第1个人的密码:");
scanf("%s",p1->passwd);
p1->id = 1;
for(i = 1;i < num;i++)
{
p2 = (struct josepf *)malloc(LEN);
printf("请输入第%d个人的密码:",i+1);
scanf("%s",p2->passwd);
p2->id = i+1;
p1->next = p2;
p1 = p2;
}
p1->next = head;
tail = p1;
joseph(head,tail,firstpasswd);
return 0;
}
二:法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
典型的递归问题,先上代码
#include<stdio.h>
int times = 1;
void move(char x,int floor,char z)
{
times++;
printf("将第%d层从 %c 移动到 %c\n",floor,x,z);
}
void hanoi(int floor,char x,char y,char z) //将x上以y为辅助塔移动到z上.
{
if(floor == 1)
{
move(x,1,z);
}
else
{
hanoi(floor-1,x,z,y); //将x上以z为辅助塔移动到y上
move(x,floor,z);
hanoi(floor-1,y,x,z); //将y上以x为辅助塔移动到z上 这三步基本上是从宏观上把握,实际上移动的只有move函数
}
}
int main(int argc,char *argv[])
{
int floor;
printf("请输入塔的层数:");
scanf("%d",&floor);
hanoi(floor,'x','y','z');
printf("总的移动次数:%d\n",times);
}
总结:有关递归问题,既精妙又复杂,这是一种形式上简单但是内部复杂的模型,我们要做的就是找到最基本的步骤,即整个过程再重复什么事,当然大过程和小过程重复的事情必须是一样的, 然后总结出解决一个小过程的方法,然后解决大的问题就好了。
版权声明:本文为博主原创文章,未经博主允许不得转载。
"递归"实现"约瑟夫环","汉诺塔"的更多相关文章
- JAVA递归算法及经典递归例子 对于这个汉诺塔问题
前言:递归(recursion):递归满足2个条件 1)有反复执行的过程(调用自身) 2)有跳出反复执行过程的条件(递归出口) 第一题:汉诺塔 对于这个汉诺塔问题,在写递归时,我们只需要确定两个条件: ...
- C#中汉诺塔问题的递归解法
百度测试部2015年10月份的面试题之——汉诺塔. 汉诺塔就是将一摞盘子从一个塔转移到另一个塔的游戏,中间有一个用来过度盘子的辅助塔. 百度百科在此. 游戏试玩在此. 用递归的思想解决汉诺塔问题就是分 ...
- python汉诺塔问题的递归理解
一.问题背景 汉诺塔问题是源于印度一个古老传说. 源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下 ...
- [Python3 练习] 006 汉诺塔2 非递归解法
题目:汉诺塔 II 接上一篇 [Python3 练习] 005 汉诺塔1 递归解法 这次不使用递归 不限定层数 (1) 解决方式 利用"二进制" (2) 具体说明 统一起见 我把左 ...
- Conquer and Divide经典例子之汉诺塔问题
递归是许多经典算法的backbone, 是一种常用的高效的编程策略.简单的几行代码就能把一团遭的问题迎刃而解.这篇博客主要通过解决汉诺塔问题来理解递归的精髓. 汉诺塔问题简介: 在印度,有这么一个古老 ...
- [python]汉诺塔问题
相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏.该游戏是在一块铜板装置上,有三根杆(编号A.B.C),在A杆自下而上.由大到小按顺序放置64个金盘(如下图).游戏的目标:把A杆上的金盘全部 ...
- 算法笔记_013:汉诺塔问题(Java递归法和非递归法)
目录 1 问题描述 2 解决方案 2.1 递归法 2.2 非递归法 1 问题描述 Simulate the movement of the Towers of Hanoi Puzzle; Bonus ...
- C#递归解决汉诺塔问题(Hanoi)
using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace MyExamp ...
- Hanio汉诺塔代码递归实现
1.背景介绍 Hanio (汉诺塔,又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘 ...
随机推荐
- yii2史上最简单式安装教程,没有之一
写一篇绝对堪称史上最easy的Yii2安装教程教你入门. 既然是安装Yii,我们先去官网下载一份Yii的高级模版,什么,你说打开页面乱七八糟的英文字母你看不懂?那这样大哥,你按照下面的截图进行操作好吧 ...
- myeclipse构建webservice项目
新建server端 1 创建Web Service Project项目 2.项目名称:HelloWorldServer 3.创建接口类 4.发布 选择项目名称,选择从Java类中构建web servi ...
- RabbitMQ、Rdis
RabbitMQ RabbitMQ:官方网址:http://www.rabbitmq.com/ Install Erlang # rpm -ivh erlang-18.3-1.el6.x86_64.r ...
- VS2012 InstallShield2013LimitedEdition激活
VS2012 InstallShield2013LimitedEdition激活 在实际开发工作中由于升级操作系统后,不知何种原因,导致 InstallShield2013LimitedEdition ...
- sql:劳务统计各分公司管理费用明细合计(等同汇总报表)
select gl_balance.year, bd_accsubj.dispname, sum(gl_balance.debitamount) 收入, sum(gl_balance.creditam ...
- 【原】灵活运用sessionStorage或者localStorage
有时,一个app中,后台并没有提供页面中对应的信息接口,需要前端在页面跳转时把某些信息带入下一个页面,一般想到用url后带参数的方法,但是有时需要带的参数过长,就不适合用这个方法了,所以用sessio ...
- 实践最简单的项目:WC
wc.exe是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命令行程序,模仿已有的wc.exe的功能,并加以扩充,给出某程序设计源语言文件的字符数.单词数和行数. 给实现一 ...
- 彻底弄懂响应式设计中的em和rem
前一阵子在响应式开发中遇到了em和rem的问题,也上网搜过一些文章,篇幅很长,也没有仔细看,今天来总结一下. rem是指:根元素(root element,html)的字体大小, em是指:父元素的字 ...
- phpstrom 10 激活
随着 JetBrains 新版本的发布,注册机已然不行了.然而,道高一尺,魔高一丈.IntelliJ IDEA开源社区 提供了如下通用激活方法:注册时选择License server填写http:// ...
- dedecms 图片集上传时提示错误信息“(FILEID:1|2|3..)“的解决
网上看到很多朋友遇到使用织梦程序一段时间后,发现上传图集时候老是失败,提示"提示FILEID:X错误,缩略图显示为红色Error"下面截图错误: 这问题今天也让我头疼了半天,好好的 ...