约瑟夫问题的另类java实现

下班到家后,看到CSDN上一篇关于约瑟夫问题的讨论,然后本人的小宇宙也耐不住了,要知道大学时算法问题曾难住过我,于是本人迅速打开eclipse开写,以下是实现部分:

/**
 * 约瑟夫问题编码解答
 */
public class JosephusMain {
    public static void main(String[] args) {
        int m = 120; //总数为m
        int k = 67; //第一次从第k个开始数
        int n = 28; //每次都要从1到n,第n个数出列

        LinkItem first = new LinkItem(1, null);
        LinkItem end = initLink(first, m);
        end.next = first;

        System.out.println("data is ready: " + first.toString() + "&" + end.toString() + "\n");

        calculate(getk(first, k), n);
    }

    /**
     * 初始化链表
     *
     * @param item
     * @param count 链表长度
     * @return 返回末端链表元素
     */
    private static LinkItem initLink(LinkItem item, int count) {
        if (item.value == count) {
            return item;
        }
        item.next = new LinkItem(item.value + 1, null);
        return initLink(item.next, count);
    }

    /**
     * 获取从first开始的第k个值
     *
     * @param first
     * @param k
     * @return 返回第k个值
     */
    private static LinkItem getk(LinkItem first, int k) {
        LinkItem itemK = first;
        int index = 1;
        while (index < k) {
            itemK = itemK.next;
            index++;
        }
        return itemK;
    }

    /**
     * 约瑟夫环实现
     *
     * @param first
     * @param n
     */
    private static void calculate(LinkItem first, int n) {
        LinkItem last = getk(first, n - 1);
        LinkItem delete = last.next;
        System.out.println(delete.toString());
        if (last == delete) {
            return;
        }
        last.next = delete.next;
        calculate(last.next, n);
    }
}


链表定义:

public class LinkItem {
    public int value;
    public LinkItem next;

    public LinkItem(int value, LinkItem next) {
        this.next = next;
        this.value = value;
    }

    @Override
    public String toString() {
        return "LinkItem{" +
                "value=" + value +
                '}';
    }
}


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

这个问题的解法是先算出30人的出列顺序,然后在前15个出列的位置上分别站上一个位非教徒,这算是逆向思路求解啦。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值