约瑟夫问题JAVA算法

       去年学院举办的算法设计比赛,当时使用的c语言来描述的,而且当时刚刚学了数据结构。于是就用到循环链表来解决,虽然答案没有完全出来,但是评分的老师,看了我的代码和思路,也许是半个感情分,毕竟是学校的算法比赛,不是正规的比赛,于是给了半钩。
       现在学了Java语言,重新用java来解决这个问题。
  百度百科对约瑟夫问题的描述:据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第 k个人。接着,再越过k-1个人,并杀掉第 k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
  这个算法算出最后一个自杀的人的号码:

    public class Josephus {
        
        public staticvoid main(String[] args){
            boolean a[]= new boolean[10];
            for(int i= 0; i < a.length; i++){
                a[i]= true;
            }        
            
            int dieNumber = 3;
            int leftCount = a.length;
            int index = 0;
            int count= 0;
            while(leftCount> 1) {
                if(a[index]){
                    count++;
                    if(count% dieNumber == 0){
                        a[index]= false;
                        leftCount--;
                    }
                }
                index++;
                index %= a.length;
            }
                
            for(int i= 0; i < a.length- 1; i++){
                if(a[i]){
                    System.out.print("最后剩下的人:"+ (i+1));
                }
            }    
        }
    }


    对上面的算法的改进,定义一个整型数组,里面存放模拟的人的编号,每当有人退出该圈的时候,就把他插入数组的尾部。

    class Josephus1{
        public staticvoid main(String[] args){
            int[] a= new int[41];

            for(int i= 0; i < a.length; i++){    //对数组中的元素进行赋值
                a[i]= i + 1;    
            }
            
            int index = 0;    //声明下标,表明元素所在的位置
            for(int i= a.length; i> 0; i--){    
             index = (index + 2)% i;    //该出局的元素
                int t = a[index];                            //不要把该出局的元素抛弃,先用临时变量存储,到时候在插入到数组的末尾
                for(int j= index; j < i-1; j++){
                    a[j]= a[j+1];
                }
                a[i-1]= t;
            }
            
            //倒序输出数组
            for(int i= a.length-1; i>= 0; i--){
                System.out.print(a[i]+ " ");
            }
        }
    }

   注:该博文是本人搬家自ChinaUnix文章,去年是指2013年。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值