约瑟夫环问题--ZOJ1088

约瑟夫环问题的描述如下:假设有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;

            }

       }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值