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),求最后一个人的位置. 解题思路:因为 ...
随机推荐
- addEventListener()、attachEvent()和removeEventListener()、detachEvent()的差别?
addEventListener()和attachEvent()的差别? addEventListener:在HTML元素上绑定事件,FF.chrome.opera.safari及IE9浏览器以上的支 ...
- oracle汉字占多少字节问题
这个其实和Oracle的配置是相关的,用以下语句查询: select * from v$nls_parameters t where t.PARAMETER='NLS_CHARACTERSET'; 可 ...
- [Vue + TS] Watch for Changes in Vue Using the @Watch Decorator with TypeScript
Vue watchers allow to perform async updates as a side effect of a property change. This lesson shows ...
- [Vue @Component] Pass Vue Render Functions as Props for Powerful Patterns
Render functions open up a world of customization and control by using pure JavaScript rather than V ...
- Behavioral模式之Interpreter模式
1.意图 给定一个语言,定义它的文法的一种表示.并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 2.别名 无 3.动机 假设一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各种 ...
- Shine.js实现动态阴影效果
Shine.js 是一个用于实现美丽阴影的 JS 库. 特性 1.可动态旋转光的位置,投影出不同的阴影效果 2.可定制的阴影, 3.没有库依赖关系,AMD兼容使用基于内容的文本或框阴影 4.在浏览器支 ...
- java学习总结——你的前世今生
一.背景 JAVA语言最開始仅仅是Sun电脑(Sun MicroSystems)公司在1990年12月開始研究的一个内部项目. Sun电脑公司的一个叫做帕特里克·诺顿的project师被公司自己开发的 ...
- iconfont 不居中的问题
引用 阿里的 iconfont 发现跟我的文字不居中 页面中实际展示的时候,发现 iconfont 字体飘起来了 原因是:iconfont 的基线跟 文字 的基线不同导致的. 解决办法:给 iconf ...
- java文件和目录的增删复制
在使用java进行开发时常常会用到文件和目录的增删复制等方法.我写了一个小工具类.和大家分享,希望大家指正: package com.wangpeng.utill; import java.io.Fi ...
- Codeforces Round #367 (Div. 2) 套题
吐槽:只能说是上分好场,可惜没打,唉 A:Beru-taxi (水题,取最小值) #include <cstdio> #include <cstring> #include & ...