分别计算从A到K每一张牌的位置。
利用循环链表,如果链表不是初始值,就说明该处有牌被抽出,需要跳过。
package com.yc.algorithm.List;
/**
* 魔术师发牌问题
* 问题描述:
* 魔术师手中有A、2、3……J、Q、K十三张黑桃扑克牌。
* 在表演魔术前,魔术师已经将他们按照一定的顺序叠放好(有花色的一面朝下)。
* 魔术表演过程为:一开始,魔术师数1,然后把最上面的那张牌翻过来,是黑桃A;
* 然后将其放到桌面上;第二次,魔术师数1、2;将第一张牌放到这些牌的最下面,
* 将第二张牌翻转过来,正好是黑桃2;第三次,魔术师数1、2、3;
* 将第1、2张牌依次放到这些牌的最下面,将第三张牌翻过来正好是黑桃3;……
* 直到将所有的牌都翻出来为止。问原来牌的顺序是如何的。
* @author yc
*/
public class MagicianLicensing {
public static void main(String[] args) {
int n = 13;
ListNode head = initList(n);
magicianLicensing(n, head);
printList(head);
}
/**
* 初始化链表
* @param n
* @return
*/
private static ListNode initList(int n) {
ListNode head = new ListNode();
ListNode tail = head;
for (int i = 0; i < n; i++) {
ListNode node = new ListNode();
tail.next = node;
tail = node;
}
tail.next = head.next;
return tail.next;
}
/**
* 打印链表
* @param head
*/
private static void printList(ListNode head) {
ListNode node = head;
while (head != node.next) {
System.out.println(node.value);
node = node.next;
}
System.out.println(node.value);
}
/**
* 魔术师问题解决
* @param n
* @param head
*/
private static void magicianLicensing(int n, ListNode head) {
head.value = 1;
for (int i = 2; i <= n; i++) {
int j = 0;
while (j < i) {
head = head.next;
if (head.value == 0)
j++;
}
head.value = i;
}
}
}