您的位置:首页 > 其它

约瑟夫环问题--ZOJ1088

2013-03-20 16:01 323 查看
约瑟夫环问题的描述如下:假设有n个人围成一圈,其编号依次为1, 2, 3, ..., n,现在使这n个人围成一圈,随机抽取一个人并将其剔除;之后依次选取与被剔除人相隔m的人并将其剔除,直到最后剩下一个人。这类问题可以给定最后剩下的人的编号以及n,求解最小的m的值;或者给定n和m,求最后剩下的人的编号。

此类问题解决思路是采用递推法,对于编号为1, 2, 3, ..., n的人,假设我们首先剔除的是编号为k(k = m%n)的人,那么剩下的人的编号为:

1, 2, 3, ... , k-1, k+1, k+2, ..., n-1, n (总共n-1人)

我们将剩下的人的编号做一下映射:

k+1 -----> 1

k+2 -----> 2

k+3 -----> 3

........

n -----> n-k

1 -----> n-k+1

.......

k-1 -----> n-1

由此,我们将问题转化为n-1个人围成一圈,每隔m个人进行剔除,并且编号有如下对应关系:

Josephus(n) = (Josephus(n-1) + k) %n = (Josephus(n-1) + m%n)

因此,约瑟夫环问题可以通过以上递推关系以及Josephus(1) = 0来求解,如ZOJ1088所述问题:

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1088

解决该问题的java代码如下所述:

import java.util.Scanner;

public
class ZOJ1088 {
public
static
void main(String[] args) {
Scanner
scanner = new Scanner(System.in);
int n = scanner.nextInt();
while(n != 0){
for(int
i = 2; ; i++){
if(Josephus(n-1, i) == 0){
System.out.println(i);
break;
}
}
n = scanner.nextInt();
}
}
public
static
int Josephus(int
n, int i){
if(n == 1)
return 0;
else{
return (Josephus(n-1,i)+i)%n;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: