丢手帕问题,约瑟夫问题(集合实现)

丢手帕问题,约瑟夫问题(集合实现)

  • 题目:

    约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的人的序号为5,4,6,2,3。最后剩下1号。

  • 思路:

    网上有很多的解决方法,有用链表,用一个循环链表来解决问题。但是,我的第一个想法是用集合,集合的内部的实现,当然也是用上链表的思想,想着java已经提供了方便的集合,那为什么不用呢?而且,也不需要变成循环链表这么复杂,只需要用一个flag来标记,当到flag到达最后的时候,再从头再来,就是了。

  • 集合实现代码:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/*
 * 题目:对手帕问题,约瑟夫问题
 * N个人围成一圈,从第一个开始报数,第M个将被杀掉,然后从下一个开始报数,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,
 * 被杀掉的人的序号为5,4,6,2,3。最后剩下1号。
 * 解题思路:
 * 使用list集合,数到相应的位置就remove,
 * 用flag来标记,到底删除哪一个,碰到末尾就从头开始数,并用余数来巧妙地得到该删除哪一个
 */
public class Main{
    public static void main(String[] args){
        Scanner jin=new Scanner(System.in);
        Main main=new Main();
        while(jin.hasNext()){
            int N=jin.nextInt();
            int M=jin.nextInt();
            main.killLast(N, M);
        }
    }
    public void killLast(int N,int M){
        List<Integer> personList=new ArrayList<Integer>();
        //初始化n个人围成一圈,初始化1~N
        for(int x=0;x<=N;x++){
            personList.add(new Integer(x));
        }
        int mod=-1;//初始化余数
        int flag=1;//默认标记到第一个人
        //判断杀掉哪一个人
        while(personList.size()!=2){//默认从0开始数,为了对应1~N,所以最后跳出循环是有2个
            flag+=(M-1);//将要标记杀掉的那个人
            mod=flag%(personList.size()-1);//使flag永远在圈内人数范围内循环移动,personList.size()-1是因为要数当前的这个位置
            if(mod==0)
                flag=(personList.size()-1);//mod=0,刚好整除,flag标记到最后一位
            else
                flag=mod;
            System.out.print(personList.remove(flag)+" ");
        }
        System.out.println();
        System.out.println(personList.get(1));
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值