据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏 。
17世纪的法国数学家加斯帕在《数目的游戏问题》中讲了这样一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。
*问题分析与算法设计
约瑟夫问题并不难,但求解的方法很多;题目的变化形式也很多。这里给出一种实现方法。
题目中30个人围成一圈,因而启发我们用一个循环的链来表示。可以使用结构数组来构成一个循环链。结构中有两个成员,其一为指向下一个人的指针,以构成环形的链;其二为该人是否被扔下海的标记,为1表示还在船上。从第一个人开始对还未扔下海的人进行计数,每数到9时,将结构中的标记改为0,表示该人已被扔下海了。这样循环计数直到有15个人被扔下海为止。
约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的人的序号为5,4,6,2,3。最后剩下1号。
假定在圈子里前K个为好人,后K个为坏人,你的任务是确定这样的最少M,使得所有的坏人在第一个好人之前被杀掉。

解决方案:

/*************************************************************************
> File Name: josefu.c
> Author: Baniel Gao
> Mail: createchance@163.com
> Blog: blog.csdn.net/createchance
> Created Time: Thu 19 Dec 2013 03:08:21 PM CST
************************************************************************/
#include <stdio.h>
#include <stdlib.h> typedef struct josefu
{
int data;
struct josefu *next;
} josefu_list; josefu_list *josefu_init(int num);
josefu_list *josefu_begin(josefu_list *list, int rule);
josefu_list *josefu_node(int num);
int josefu_free(josefu_list *list); int main(void)
{
josefu_list *list;
int num, rule; puts("Please input number and rules: ");
scanf("%d%d", &num, &rule);
list = josefu_init(num);
list = josefu_begin(list, rule); josefu_free(list); return 0;
} josefu_list *josefu_init(int num)
{
int i;
josefu_list *new;
josefu_list *list = josefu_node(1); for(i = num; i > 1; i--) {
new = josefu_node(i);
new->next = list->next;
list->next = new;
} return list;
} josefu_list *josefu_node(int num)
{
josefu_list *p = NULL; p = (josefu_list *)malloc(sizeof(josefu_list));
p->data = num;
p->next = p; return p;
} josefu_list *josefu_begin(josefu_list *list, int rule)
{
int counter;
josefu_list *tmp = NULL; for(counter = 1; list->next != list; counter++) {
if(counter == rule - 1) {
tmp = list->next;
list->next = tmp->next;
free(tmp);
counter = 0;
josefu_show(list);
}
list = list->next;
} return list;
} int josefu_show(josefu_list *list)
{
josefu_list *p = list; if(list == NULL)
return 0; do {
printf("%5d",p->data);
p = p->next;
} while(list != p);
putchar('\n');
} int josefu_free(josefu_list *list)
{
free(list); return 0;
}

运行实例:





C语言单向循环链表解决约瑟夫问题的更多相关文章

  1. C++循环链表解决约瑟夫环问题

    约瑟夫环问题可以简单的使用数组的方式实现,但是现在我使用循环链表的方法来实现,因为上午看到一道面试题规定使用循环链表解决约瑟夫环问题. 什么是约瑟夫环? “约瑟夫环是一个数学的应用问题:已知n个人(以 ...

  2. 关于单向循环链表的约瑟夫问题(Java实现)

    关于单向循环链表的约瑟夫问题(Java实现) 最近在学习链表时,遇到单向循环链表中的约瑟夫问题.在构建循环链表的代码上,我有一点很不理解,遂记录下来. Josephu问题为: 设编号为1, 2,.. ...

  3. 使用java的循环单向链表解决约瑟夫问题

    什么是约瑟夫问题 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定 ...

  4. Java 用单向循环链表实现 约瑟夫问题

    public class lianbiao2 { class Node{ Node next; int number; public Node getNext() { return next; } p ...

  5. golang数据结构之用循环链表解决约瑟夫环问题

    josephu.go package link import ( "fmt" ) type Kid struct { ID int next *Kid } func AddKid( ...

  6. 基于visual Studio2013解决算法导论之021单向循环链表

     题目 单向循环链表的操作 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <time.h> ...

  7. C语言解决约瑟夫问题详解的代码

    将开发过程中比较重要的一些内容做个收藏,下面的内容是关于C语言解决约瑟夫问题详解的内容,希望能对码农有帮助. #pragma once #include<vector> class PRO ...

  8. 单向循环链表C语言实现

    我们都知道,单向链表最后指向为NULL,也就是为空,那单向循环链表就是不指向为NULL了,指向头节点,所以下面这个程序运行结果就是,你将会看到遍历链表的时候就是一个死循环,因为它不指向为NULL,也是 ...

  9. c语言实现--单向循环链表操作

    1,什么叫单向循环链表.单向循环链表是指在单链表的基础上,表的最后一个元素指向链表头结点,不再是为空. 2,由图可知,单向循环链表的判断条件不再是表为空了,而变成了是否到表头. 3,链表的结点表示 1 ...

随机推荐

  1. WinScp上传和下载

    不多说,贴代码,看不懂得可以留言.需要引入WinSCP public class WebWinScp { //远程上传路径 private SessionOptions sessionOptions ...

  2. bzoj2535 2109

    做过4010这题其实就水了 把图反向之后直接拓扑排序做即可,我们可以用链表来优化 每个航班的最小起飞序号就相当于在反向图中不用这个点最迟到哪 type node=record po,next:long ...

  3. C#4.0新特性(3):变性 Variance(逆变与协变)

    一句话总结:协变让一个粗粒度接口(或委托)可以接收一个更加具体的接口(或委托)作为参数(或返回值):逆变让一个接口(或委托)的参数类型(或返回值)类型更加具体化,也就是参数类型更强,更明确. 通常,协 ...

  4. BZOJ2482: [Spoj1557] Can you answer these queries II

    题解: 从没见过这么XXX的线段树啊... T_T 我们考虑离线做,按1-n一个一个插入,并且维护区间[ j,i](i为当前插入的数)j<i的最优值. 但这个最优值!!! 我们要保存历史的最优值 ...

  5. 一个java高级工程师的进阶之路

    宏观方面 一. JAVA.要想成为JAVA(高级)工程师肯定要学习JAVA.一般的程序员或许只需知道一些JAVA的语法结构就可以应付了.但要成为JAVA(高级) 工程师,您要对JAVA做比较深入的研究 ...

  6. css清除浮动的两种方式(clearfix和clear)

    最近总是在用浮动,这两种方式总是浮现在眼前,或者说去掉父级和同级浮动样式总在思考中.两种方式怎么写都在base.css中. 在做瑞祥之旅的过程中,还是吃了一个大亏,就是清除浮动,不管是同级还是父级,都 ...

  7. IOS UINavigationController 操作相关集合

    1.修改中间Title字体以及大小 [self.navigationController.navigationBar setTitleTextAttributes:[NSDictionary dict ...

  8. Oracle中错误代码ORA-02292 违反了完整性约束条件解决

    百度处理: A表被B表引用,删除A表的时候提示ORA-02292,A表的主键被引用了,虽然已经把B表的数据全部删除掉,但仍然删除不了A表的数据.解决办法: 用禁用约束语句把A表的主键约束给禁用掉.1. ...

  9. STM32的JTAG、SWD和串口下载的问题

    最近有一个项目用到STM32,为了使PCB布线方便一些所以改了一些引脚,占用了JTAG接口的PA15和PB3,所以要禁用一下JTAG,下载采用SWD模式.这样在实际操作中做出一些总结(方法网上都有.这 ...

  10. 【windows核心编程】 第八章 用户模式下的线程同步

    Windows核心编程 第八章 用户模式下的线程同步 1. 线程之间通信发生在以下两种情况: ①    需要让多个线程同时访问一个共享资源,同时不能破坏资源的完整性 ②    一个线程需要通知其他线程 ...