约瑟环问题

例题:

       17世纪的法国数学家加斯帕在《数目的游戏问题》中讲的一个故事,15个教徒和15个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法,30个人围成一个圆圈,从第一个人开始依次报数,每数到第九个人,就将他扔入大海,如此循环进行,直到仅剩余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。

 

解析:题目中30个人围成一圈,可以用一个循环的链来表示,使用结构数组来构成一个循环链。结构中有两个成员,其一为指向下一个人的指针,以构成环形的链;其二为该人是否被扔下海的标记,为1表示还在船上。从第一个开始对还未扔下海的人进行计数,每数到9时,将结构中的标记改为0,表示该人已被扔下海了。这样循环计数,直到有15个人被扔下海为止。

还有一种办法:使用一个Boolean数组来模拟,非教徒站的位置为false,教徒站的位置为true。一开始,所有的位置都为true,每数到9时,则自动将true设为false,如果该位置已经为false,则设置下一个true位置为false,如果已经循环到底,则重新开始。

 


public class Solution {
    private  static class Node{
        int val;
        boolean flag;
        Node next;
        public Node(int val){
            this.val = val;
            this.flag = false;
        }
    }
    public int LastRemaining_Solution(int n, int m) {
        if(n==0||m==0)
            return -1;
        
        Node pHead = new Node(0);
        Node first = pHead;
        for(int i=1;i<n;i++){
            Node node = new Node(i);
            first.next = node;
            first = first.next;
        }
        first.next = pHead;
        
        for(int i=0;i<n-1;i++){
           int count =0;
           while(count<m-1){
               if(!pHead.flag){
                   count++;
                   pHead = pHead.next;
               }else{
                   pHead = pHead.next;
               } 
           }
           if(!pHead.flag){
               pHead.flag = true;
               while(pHead.flag){
                   pHead = pHead.next;
               }
           }else{
               while(pHead.flag){
                   pHead = pHead.next;
               }
                pHead.flag = true;
               while(pHead.flag){
                   pHead = pHead.next;
               }
           }
        }
        while(pHead.flag){
            pHead = pHead.next; 
        }
          return pHead.val;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值