约瑟夫环的解法其一

问题来源:据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
问题归纳:一群人围坐一圈,规定一个为第一个人,从他开始,规定一个方向,然后开始数数,规定每次数多少人,被数到的人将会被杀,最后只能存活一个人,问存活的那个人是谁。
解题思路:这个问题可以用数据结构中的列表解决,假设总共n个人,每次数m个人,因为m可能大于n,因为在程序中是以0为起点的,所以第一个被杀的人是c=(m-1)%n,接下来被杀的人位置则为(c+m-1)%(n-1),以此类推,最后就能得出幸存者。
实现代码:package cn.com.array;
//约瑟夫环问题
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Josepus {
public int lastRemaining(int n, int m) {

    if(n==0||m==0){
        return 0;
    }
    List<Integer>list=new ArrayList<>();
    for(int i=0;i<n;i++){
        list.add(i);

    }
    int c=(m-1)%n;
    while(list.size()!=1){
        list.remove(c);
        c=(c+m-1)%list.size();
    }
    return list.get(0);
}
public static void main(String[] args) {
    System.out.print("请输入人数n:");
    Scanner input=new Scanner(System.in);
    int n=input.nextInt();

    System.out.print("请输入从第几个人开始杀m:");
    int m=input.nextInt();
    Josepus josepus=new Josepus();
    System.out.println("第"+josepus.lastRemaining(n,m)+"个人将存活");

}

}
运行实例:
在这里插入图片描述
暂时只会这一种解法

发布了35 篇原创文章 · 获赞 3 · 访问量 540

猜你喜欢

转载自blog.csdn.net/biaogegegege1/article/details/105202671