Josephus problem(约瑟夫问题,丢手绢问题)
约瑟夫问题
约瑟夫环问题是一个数学应用题:已知n个人(以编号1,2,3.....,n)围坐在一张圆桌的周围。从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列,以此规律重复下去,直到圆桌的人全部出列。通常解决这类问题时我们把编号从0-n-1,最后+1即为原问题的解。
一、算法描述:
约瑟夫环运作如下:
- 一群人围在一起坐成环状
- 从某个编号开始报数(如:K)
- 数到某个数(如:M)的时候,此人出列,下一个人重新报数
- 一直循环,直到所有人出列 ,约瑟夫环结束
二、解决此类问题的解法
C语言 模拟递归法
公式推导法
#include <stdio.h>
#include <stdlib.h>
struct _Node
{
int data;
struct _Node *next;
};
typedef struct _Node node_t;
typedef struct _Linklist
{
node_t *phead;
node_t *ptail;
int len;
} Linklist;
static node_t *GetNode(int i) //新建并初始化节点
{
node_t *pNode;
pNode = (node_t *)malloc(sizeof(node_t));
if (!pNode)
{
printf("Error,thememoryisnotenough!\n");
exit(-);
}
pNode->data = i;
pNode->next = NULL;
return pNode;
}
void init_list(Linklist *plist) //用第一个节点初始化循环单链表
{
node_t *p;
p = GetNode();
//printf("TheNewNodeis:%d\n",p->data);//****TEST****
plist->phead = p;
plist->ptail = p;
p->next = plist->phead;
plist->len = ;
}
static void Create_List(Linklist *plist, int n) //把其余数据添加到循环单链表中
{
int i = ;
node_t *pNew;
for (i = ; i <= n; i++)
{
pNew = GetNode(i);
/********TEST********
printf("TheNewNodeis:%d\n",pNew->data);
********TEST********/
plist->ptail->next = pNew;
plist->ptail = pNew;
pNew->next = plist->phead;
plist->len++;
}
printf("Completesthee-waycirculationchaintablethefoundation!\n");
}
void Print_List(Linklist *plist) //输出链表内容
{
node_t *pCur = plist->phead;
do
{
printf("The%dperson.\n", pCur->data);
pCur = pCur->next;
} while (pCur != plist->phead);
printf("ThelengthoftheList:%d\n", plist->len);
} // 约瑟夫回环函数实现 void joseph(Linklist *plist, int m) //约瑟夫回环函数实现
{
node_t *pPre = plist->ptail;
node_t *pCur = plist->phead;
int i;
while (plist->len != )
{
i = ;
while (i < m - )
{
pPre = pPre->next;
i++;
}
pCur = pPre->next;
pPre->next = pCur->next;
free(pCur);
plist->len--;
}
printf("Thelastoneis:%d\n", pPre->data);
}
int main()
{
int n = ;
printf("PleaseinputtheLengthoftheCirclelist:");
scanf("%d", &n);
int m = ;
printf("PleaseinputtheStoppoint:");
scanf("%d", &m);
Linklist pList;
init_list(&pList);
Create_List(&pList, n);
Print_List(&pList);
joseph(&pList, m);
return ;
}
三、OJ 例题
题目描述

解题思路:
1<=n<1000发现数据量不大,直接模拟游戏求出最后一个人
下面是非递归使用for循环代码
#include <stdio.h>
#include <stdlib.h> int main()
{
int n;
while (scanf_s("%d", &n) == )
{
int len, i, j=;
int count = n;//当前存在的人数 当count == 1剩下最后一个人 即为答案
int a[] = { };//初始化模拟数组
for (i = ; i < n; i++)//人数从1~n数组标示从0~n-1
{
if (count == )
break;
if (a[i] == )//a[i]==1表示这个人已经退出游戏
{
if (j % == )
{
a[i] = ;
count--;//删掉一个人
}
else
{
if (i + >= n)//数组循环即 当i往下大于人数n时需要从0开始 但是由于是for 循环i会++ 所以i置为-1
i = -;
}
j++;
}
else
{
if (i + >= n)
i = -;//同上
}
if (i == n-)
i = -;//同上
}
for (i = ; i < n; i++)
if (a[i]==)
printf("%d\n", i + );
}
}
非递归使用while循环
#include <stdio.h>
#include <stdlib.h> int main()
{
int n;
while(scanf("%d",&n)==)
{
int i=,len,a[]={};
int flag=;
len=n-;
while(len)
{
if(a[i]==)
{
if(flag==)
{
i++;
if(i>n)
i=;
flag=;
}
else
{
a[i]=;
i++;
if(i>n)
i=;
flag=;
len--;
}
}
else
{
i++;
if(i>n)
i=;
}
}
for(i=;i<=n;i++)
if(a[i]==)
printf("%d\n",i);
}
}
题目数字较大的时候可以采用公式推导法,参考下面链接的博客
https://blog.csdn.net/u011500062/article/details/72855826
Josephus problem(约瑟夫问题,丢手绢问题)的更多相关文章
- 约瑟夫问题(Josephus Problem)的两种快速递归算法
博文链接:http://haoyuanliu.github.io/2016/04/18/Josephus/ 对,我是来骗访问量的!O(∩_∩)O~~ 约瑟夫问题(Josephus Problem)也称 ...
- 算法Sedgewick第四版-第1章基础-017一约瑟夫问题(Josephus Problem)
/************************************************************************* * * Josephus problem * * ...
- Bloomberg面经准备: Josephus problem
Given a circular single linked list.Write a program that deletes every kth node until only one node ...
- josephus Problem 中级(使用数组模拟链表,提升效率)
问题描写叙述: 在<josephus Problem 0基础(使用数组)>中.我们提出了一种最简单直接的解决方式. 可是,细致审视代码之后.发现此种方案的效率并不高,详细体如今.当有人出局 ...
- Josephus Problem的详细算法及其Python、Java实现
笔者昨天看电视,偶尔看到一集讲述古罗马人与犹太人的战争--马萨达战争,深为震撼,有兴趣的同学可以移步:http://finance.ifeng.com/a/20170627/15491157_0. ...
- python玩丢手绢问题,出局的顺序
# 丢手绢问题# 游戏规则: 有N个小朋友玩丢手绢游戏,做成一圈,从第一个小朋友开始数数,从一开始数,数到指定数字的小朋友要出列,然后下一个小朋友继续从1开始数,依次类推,算出最后一个留下来的小朋友是 ...
- NC207040 丢手绢
NC207040 丢手绢 题目 题目描述 "丢丢丢手绢,轻轻地放在小朋友的后面,大家不要告诉她,快点快点抓住她,快点快点抓住她." 牛客幼儿园的小朋友们围成了一个圆圈准备玩丢手绢的 ...
- 约瑟夫(环)问题(Josephus problem)
问题描述:皇帝决定找出全国中最幸运的一个人,于是从全国选拔出 n 个很幸运的人,让这 n 个人围着圆桌进餐,可是怎么选择出其中最幸运的一个人呢?皇帝决定:从其中一个人从 1 开始报数,按顺序数到第 k ...
- LightOJ - 1179 Josephus Problem(约瑟夫环)
题目链接:https://vjudge.net/contest/28079#problem/G 题目大意:约瑟夫环问题,给你n和k(分别代表总人数和每次要数到k),求最后一个人的位置. 解题思路:因为 ...
随机推荐
- C/C++异常处理机制
1.C语言异常处理 1.1 异常终止 标准C库提供了abort()和exit()两个函数,它们可以强行终止程序的运行,其声明处于<stdlib.h>头文件中.这两个函数本身不能检测 ...
- HDU 5015 233Matrix (构造矩阵)
233 Matrix Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Tota ...
- Android应用程序无法读写USB设备的解决方法
假设android系统中的API或者apk无法读写usb设备.可能是没有加入读写usb的权限,须要依照例如以下方法进行设置: 1. 在android.hardware.usb.host.xml文件里加 ...
- 使用JavaScript开发IE浏览器本地插件实例
使用JavaScript开发IE浏览器本地插件实例 投稿:junjie 字体:[增加 减小] 类型:转载 时间:2015-02-18我要评论 这篇文章主要介绍了使用JavaScript开发IE浏览器本 ...
- 使用引导扇区维护工具BOOTICE编辑系统启动列表BCD文件
使用引导扇区维护工具BOOTICE编辑系统启动列表BCD文件 系列文章: 笔记本电脑提速之加装内存条.SSD固态硬盘.光驱位换SSD固态硬盘 笔记本ThinkPad E430c加装内存和SSD固态硬盘 ...
- 学习C语言,困难吗?
要说计算机如今什么最火.无异于网络.看看各大计算机站点,满眼尽是网络project师,什么IP啊,路由啊,虚拟机啊,总之,操作性的计算机技能牢牢占领了半壁江山. 这些技巧当然重要.可是 ...
- Wordpress的安装 for mac
1.服务器环境要求 PHP 5.2.4或更新版本 MySQL 5.0或更新版本 Apache mod_rewrite模块(可选,用于支持“固定链接”和“站点网络”功能) 选择安装:XAMPP 2.XA ...
- 一个APP爆炸的时代,假设没有wifi
我们每天都离不开的微信,又传来了一个新消息.你造?微信公众平台新增了设备功能.眼下可支持可穿戴设备,将来呢,前景不可限量!能够想象,"后果"是我们越来越离不开微信,依附于它.这样的 ...
- bzoj 1453 双面棋盘
题目大意: 一个黑白方格图 支持单点修改 查询黑色与白色联通快个数 思路: 可以把每一行压为一个点 使用线段树来维护 然后两行合并的时候使用并查集来合并 #include<iostream> ...
- P1402 酒店之王 网络流
大水题,我自己瞎做就做出来了,没啥说的,zz建图,就是板子. 题干: 题目描述 XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的房间色调.阳光等, ...