接着上篇猴子选大王继续展开,上篇讲的是有m个猴子,从第一个猴子开始报数,当报到n时,第n个猴子出去,从n+1猴子开始,从1继续报数。
这篇我们来说,从任意猴子k的位置开始报数,当报到n时,第n个猴子出去,从n+1猴子开始,从1继续报数
问题描述:
约瑟夫环运作如下: 1、一群猴子围在一起坐成环状(如:N) 2、从某个编号开始报数(如:K) 3、数到某个数(如:M)的时候,此猴出列,下一个猴子重新报数 4、一直循环,直到所有猴子出列,约瑟夫环结束,同时输出最后的大王。
解题思路:
我们还是用循环链表解决,这里有两种方法,一种是根据上篇讲的那样,构造循环链表,利用循环操作将头指针指向第k个结点上,后续操作和上篇一样
public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入猴子数N: "); int n = sc.nextInt(); System.out.println("请输入开始报数编号K: "); int k = sc.nextInt(); System.out.println("请输入出列数M: "); int m = sc.nextInt(); if(k > n || m > n) { System.out.println("编号K或者M不能大于猴子总数N"); System.exit(0); } ListNode head = createListNode(n); while(k != 1){ head = head.next; k--; } int count = 1; ListNode pre = null; while(head.next != head){ pre = head; head = head.next; count++; if(count == m){ System.out.println("当前出局人是: "+ head.val); pre.next = head.next; head = pre.next; count = 1; } } System.out.println("最后的大王是: "+ head.val); } public static ListNode createListNode(int m){ ListNode head = new ListNode(1); if(m == 1) return head; ListNode cur = head; for(int i = 2;i <= m;i++){ ListNode tmp = new ListNode(i); cur.next = tmp; cur = tmp; } cur.next = head; return head; } }
另一种就是在构造循环链表过程中,直接将头指针定义为第k个猴子,后续操作和上篇代码一样
public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入猴子数N: "); int n = sc.nextInt(); System.out.println("请输入开始报数编号K: "); int k = sc.nextInt(); System.out.println("请输入出列数M: "); int m = sc.nextInt(); if(k > n || m > n) { System.out.println("编号K或者M不能大于猴子总数N"); System.exit(0); } ListNode head = createListNode(n, k); int count = 1; ListNode pre = null; while(head.next != head){ pre = head; head = head.next; count++; if(count == m){ System.out.println("当前出局人是: "+ head.val); pre.next = head.next; head = pre.next; count = 1; } } System.out.println("最后的大王是: "+ head.val); } public static ListNode createListNode(int n,int k){ ListNode head = new ListNode(k); ListNode cur = head; for(int i = k;i<n;i++){ ListNode tmp = new ListNode(i + 1); cur.next = tmp; cur = tmp; } for(int i = 0;i<k - 1;i++){ ListNode tmp = new ListNode(i + 1); cur.next = tmp; cur = tmp; } cur.next = head; return head; }