C/C++02: Josephus问题
据说著名犹太历史学家Josephus有过以下的故事:
在罗马人占领乔塔帕特後,39个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。
然而Josephus和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
用循环列表的数据结构是比较容易实现的,下面是我曾经用数组的方法(纯粹是为了玩一玩)完成的C程序,应该在实现上还可以有改进。
1 #include <stdio.h> 2 3 int main() 4 { 5 int N = 41; 6 int i = 1; 7 int m = 3; 8 int MAX = N; 9 int k, t; 10 int a[100], b[100]; 11 for (k = 0; k < N; k++) 12 { 13 b[k] = k + 1; 14 } 15 for(k = 0; k < MAX; k++) 16 { 17 t = (i + m - 1) % N; 18 if (t - 1 < 0) 19 { 20 a[k] = b[N-1]; 21 i = N; 22 } 23 else 24 { 25 a[k] = b[t-1]; 26 i = t; 27 while (t < N) 28 { 29 b[t-1] = b[t]; 30 t++; 31 } 32 } 33 N = N - 1; 34 printf("%i ", a[k]); 35 } 36 printf("\n"); 37 return 0; 38 }