关于约瑟夫问题的那点事
来源:互联网 发布:php股票价格实时刷新 编辑:程序博客网 时间:2024/06/06 08:51
说到约瑟夫,你可能会想起到的是约瑟夫.摩根《吸血鬼日记》里的混血始祖克劳斯......但我们今天要说一说著名的约瑟夫问题。
约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环。又称“丢手绢问题”.)。
约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。
在此,有一个有趣的小故事:据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏(学霸用事实证明知识就是力量!)。
简单的说就是i个人(编号1~i),从1开始报数,报到m的退出,剩下的人继续从1开始报数。求最后一个留下的人的编号。
我们知道第一个人(编号一定是m) 出列之后,剩下的i-1个人组成了一个新的约瑟夫环
令f表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f[n]
递推公式
f[1]=0;
f=(f+m) mod i; (i>1)
下面用循环链表实现设个问题:
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
int data;
struct Node* next;
}node_t;
#include<stdlib.h>
typedef struct Node
{
int data;
struct Node* next;
}node_t;
typedef struct Linklist
{
node_t *phead;
node_t *ptail;
int len;
}Linklist;
static node_t *GetNode(int i) //初始化节点
{
node_t*pNode=NULL;
pNode=(node_t*)malloc(sizeof(node_t));
if(!pNode)
{
printf("Error,out of memroy\n");
exit(-1);
}
pNode->data=i;
pNode->next=NULL;
return pNode;
}
void init_list(Linklist*plist) //用第一个节点初始化循环单链表
{
node_t*p;
p=GetNode(1);
plist->phead=p;
plist->ptail=p;
p->next=plist->phead;
plist->len=1;
}
static void Create_List(Linklist*plist,int n) //把数据添加到循环单链表中
{
int i=0;
node_t*pNew;
for(i=2;i<=n;i++)
{
pNew=GetNode(i);
plist->ptail->next=pNew;
plist->ptail=pNew;
pNew->next=plist->phead;
plist->len++;
}
printf("约瑟夫环的序列为:\n");
}
void Print_List(Linklist*plist) //输出链表内容
{
node_t*pCur=plist->phead;
do
{
printf("%d\n",pCur->data);
pCur=pCur->next;
}
while(pCur!=plist->phead);
printf("共有人数:%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!=1)
{
i=0;
while(i<m-1)
{
pPre=pPre->next;
i++;
}
pCur=pPre->next;
pPre->next=pCur->next;
free(pCur);
plist->len--;
}
printf("最后幸存者是:%d\n",pPre->data);
}
int main()
{
int n=0;
int m=0;
Linklist pList;
printf("输入约瑟夫环的人数:");
scanf("%d",&n);
printf("输入报的数:");
scanf("%d",&m);
init_list(&pList);
Create_List(&pList,n);
Print_List(&pList);
joseph(&pList,m);
system("pause");
return 0;
}
{
node_t *phead;
node_t *ptail;
int len;
}Linklist;
static node_t *GetNode(int i) //初始化节点
{
node_t*pNode=NULL;
pNode=(node_t*)malloc(sizeof(node_t));
if(!pNode)
{
printf("Error,out of memroy\n");
exit(-1);
}
pNode->data=i;
pNode->next=NULL;
return pNode;
}
void init_list(Linklist*plist) //用第一个节点初始化循环单链表
{
node_t*p;
p=GetNode(1);
plist->phead=p;
plist->ptail=p;
p->next=plist->phead;
plist->len=1;
}
static void Create_List(Linklist*plist,int n) //把数据添加到循环单链表中
{
int i=0;
node_t*pNew;
for(i=2;i<=n;i++)
{
pNew=GetNode(i);
plist->ptail->next=pNew;
plist->ptail=pNew;
pNew->next=plist->phead;
plist->len++;
}
printf("约瑟夫环的序列为:\n");
}
void Print_List(Linklist*plist) //输出链表内容
{
node_t*pCur=plist->phead;
do
{
printf("%d\n",pCur->data);
pCur=pCur->next;
}
while(pCur!=plist->phead);
printf("共有人数:%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!=1)
{
i=0;
while(i<m-1)
{
pPre=pPre->next;
i++;
}
pCur=pPre->next;
pPre->next=pCur->next;
free(pCur);
plist->len--;
}
printf("最后幸存者是:%d\n",pPre->data);
}
int main()
{
int n=0;
int m=0;
Linklist pList;
printf("输入约瑟夫环的人数:");
scanf("%d",&n);
printf("输入报的数:");
scanf("%d",&m);
init_list(&pList);
Create_List(&pList,n);
Print_List(&pList);
joseph(&pList,m);
system("pause");
return 0;
}
看了这篇文章,你是不是对约瑟夫问题理解了呢
3 0
- 关于约瑟夫问题的那点事
- Java 关于重载的那点问题
- 关于ubuntu开机的那点问题
- 关于上司的那点事
- 关于黑客的那点事
- 关于8086的那点事
- 关于程序员的那点事
- 关于计算机的那点事
- 关于CGI的那点事
- 关于彩虹表的那点事
- 关于铁道部的那点事
- 关于JAVA集合的那点事
- 关于模式的那点事
- 关于vs2010的那点事
- 关于connectionstring字符串的那点事
- 关于公司的那点事
- IOS 关于分辨率的那点事
- 关于进程的那点事
- 如何添加AdMob广告到现有的Unity3D ios游戏
- Openlayers加载在线地图
- Python核心编程(第十四章)--执行环境
- js常用返回网页顶部几种方法
- Unity3D研究院之IOS全自动打包生成ipa
- 关于约瑟夫问题的那点事
- .NET程序集的类型和部署方式
- struts2中的constant配置详解
- scala学习三:scala面向对象
- checkStyle 总结
- 条件区分逻辑代码构建设计
- 【Android 基础】使用getActionBar()报空指针异常的解决方法
- 技术杂谈——腾讯视频格式转MP4
- IOS 懒加载