您的位置:首页 > 其它

Joseph问题

2017-12-26 21:47 134 查看
题目描述:

原始的Joseph问题描述如下:有n个人围坐在一个圆桌周围,把这n个人依次编号为1、2、3……n。从编号是1的人开始数,数到第m个人出列,然后从出列的下一个人重新开始报数,数到第m个人时又出列,以此类推。当n=6,m=5时,出列顺序依次是5,4,6,2,3,1。

现在的问题是:假设有k个好人和k个坏人。好人的编号是1到k,坏人的编号是k+1到2k。我们希望求出m的最小值,使得先出列的k个人都是坏人。

【输入】

4

【输出】

30

思考:要使得先出列的人都是坏人,m的值必定在k-2k的倍数这个区间,也就是m=a*k+b,a为奇数,1<=b<=k 。

为方便计算,设编号从0开始排,0–k-1 是好人。

#include "malloc.h"
#include "stdio.h"
int joseph(int k) {

int m, t, a = 1, k1, i, n;
while (1) {
for (k1 = 1; k1 <= k; k1++) {  // 按a奇数倍增m,循环k次,找满足m=a*k+k1区间内的值
m = a * k + k1;         //由第一轮可知m定满足这个约束,a为奇
t = 0, n = 2 * k;
for (i = 1; i <= k; i++) { // 其中每个取值需循环判断k次,每次都满足则成功
t = (t + m - 1) % n;
if (t < k)
break;
n--;                  //计数总数-1
}
if (i > k)
return m;
}// end for( k1...
a += 2;    // a 系数内查找失败,下一个奇数倍
}

}

int main()
{
int k;
scanf("%d", &k);

printf("%d", joseph(k));

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  joseph