约瑟夫环
来源:互联网 发布:淘宝运费险理赔价格表 编辑:程序博客网 时间:2024/05/29 08:36
约瑟夫环
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解。
C语言
递归法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include<stdio.h>
#include<stdlib.h>
struct_Node
{
intdata;
struct_Node*next;
};
typedefstruct_Nodenode_t;
typedefstruct_Linklist
{
node_t*phead;
node_t*ptail;
intlen;
}Linklist;
staticnode_t*GetNode(inti)
//新建并初始化节点
{
node_t*pNode;
pNode=(node_t*)
malloc
(
sizeof
(node_t));
if
(!pNode)
{
printf
(
"Error,thememoryisnotenough!\n"
);
exit
(-1);
}
pNode->data=i;
pNode->next=NULL;
returnpNode;
}
voidinit_list(Linklist*plist)
//用第一个节点初始化循环单链表
{
node_t*p;
p=GetNode(1);
//printf("TheNewNodeis:%d\n",p->data);//****TEST****
plist->phead=p;
plist->ptail=p;
p->next=plist->phead;
plist->len=1;
}
staticvoidCreate_List(Linklist*plist,intn)
//把其余数据添加到循环单链表中
{
inti=0;
node_t*pNew;
for
(i=2;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"
);
}
voidPrint_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);
}
约瑟夫回环函数实现
voidjoseph(Linklist*plist,intm)
//约瑟夫回环函数实现
{
node_t*pPre=plist->ptail;
node_t*pCur=plist->phead;
inti;
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
(
"Thelastoneis:%d\n"
,pPre->data);
}
intmain()
{
intn=0;
printf
(
"PleaseinputtheLengthoftheCirclelist:"
);
scanf
(
"%d"
,&n);
intm=0;
printf
(
"PleaseinputtheStoppoint:"
);
scanf
(
"%d"
,&m);
LinklistpList;
init_list(&pList);
Create_List(&pList,n);
Print_List(&pList);
joseph(&pList,m);
return0;
}
非递归法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<stdio.h>
#defineM200
intmain
inttemp=0;
intb=1,k=0;
for
(inti=1;i<=M;i++)
temp=b+3*k;
if
(i==temp)
//规则2:若上一组数字为最后保留号与人数相等,则下一数从2开始记。
b=2;
k=0;
continue
;
elseif(i-temp==1)
//规则1:若上一组数字为最后保留号比人数少一,则下一数从1开始记。
{b=1;k=0;
continue
;}
k++;
printf
(
"%d%d"
,M,temp);
return0;
【PHP模拟】
php有非常完善的数据结构模拟方案,可以非常简洁的解决这样的问题.
当然数量级太大那还是使用数学方法吧!$m>$n的情况也能行,想优化效率不知道该怎么写了.请大神补充吧!
functionking($n,$m){
$monkey=range(1,$n);
//模拟建立一个连续数组
$i=0;
while
(count($monkey)>1){
$i+=1;
//开始查数
$head=array_shift($monkey);
//直接一个一个出列最前面的猴子
if
($i%$m!=0){
array_push($monkey,$head);
//如果没数到m或m的倍数,则把该猴放回尾部去.
}
//否则就抛弃掉了
}
return
$monkey[0];
}
echo
'剩余'
,king(3,4),
'号猴子'
;
0 0
- 约瑟夫问题、约瑟夫环
- 约瑟夫环
- 约瑟夫环
- 约瑟夫环
- 约瑟夫环
- 约瑟夫环
- 约瑟夫环
- 约瑟夫环
- 约瑟夫环
- 约瑟夫环
- 约瑟夫环
- 约瑟夫环
- 约瑟夫环
- 约瑟夫环
- 约瑟夫环
- 约瑟夫环
- 约瑟夫环
- 约瑟夫环
- MyBatis中Like语句使用方式
- hdu 1789 Doing Homework again
- 最常用的1000个Java类(附代码示例)
- java动态代理(JDK和cglib)
- Swift-实例方法
- 约瑟夫环
- mysql读写分离原理是什么
- javaweb基础(mysql)
- Ajax实现页面局部更新
- 二,Spring事件机制
- ARM汇编程序AXD调试出现00000000 [0xe7ff0010] dci 0xe7ff0010 ; ? undefined 00000004 [0xe800e800] stmd
- 全排列
- 分享如何使用PHP将URL地址参数进行加密传输提高网站安全性
- js+css实现点击导航条“登录”弹出登录框界面