魔术师发牌问题(循环链表)

问题描写叙述:

       魔术师手中有A、2、3……J、Q、K十三张黑桃扑克牌。在表演魔术前,魔术师已经将他们依照一定的顺序叠放好(有花色的一面朝下)。魔术表演过程为:一開始,魔术师数1,然后把最上面的那张牌翻过来,是黑桃A;然后将其放到桌面上;第二次,魔术师数1、2;将第一张牌放到这些牌的最以下,将第二张牌翻转过来,正好是黑桃2;第三次,魔术师数1、2、3;将第1、2张牌依次放到这些牌的最以下,将第三张牌翻过来正好是黑桃3;……直到将全部的牌都翻出来为止。问原来牌的顺序是怎样的。

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #define Carnumber 13
 4 
 5 typedef struct Node{
 6     int data;
 7     struct Node *next;
 8 }Node,*linklist;
 9 
10 //初始化 
11 int InitList(linklist &head){
12     head = (linklist)malloc(sizeof(Node));
13     if(!head)
14         return 0;
15     head->next = NULL;
16     return 0;
17 }
18 
19 //创建 
20 linklist CreatLinkList(linklist &head){
21     linklist s,r;
22     r = head;
23     for(int i = 1; i <= Carnumber; i++){
24         s = (linklist)malloc(sizeof(Node));
25         s->data = 0;//链表初始化0,开始时候不存扑克牌内容
26         r->next = s;
27         r = s;
28     }
29     r->next = NULL;
30     s->next = head->next;//尾部指向head,构成单循环链表 
31     return s->next;
32 }
33 
34 //发牌顺序计算 
35 void Magician(linklist &head){
36     linklist p;
37     int j;
38     int Countnumber = 2;
39     p = head;
40     p->data = 1;//第一张牌放1
41     while(1){
42         for(j = 0; j < Countnumber; j++){
43             p = p->next;
44             if(p->data != 0){//如果该位置有牌,则下一个 
45                 p->next;
46                 j--;
47             }
48         }
49         if(p->data == 0){
50             p->data = Countnumber;
51             Countnumber++;
52             if(Countnumber == 14)
53                 break;
54         } 
55     } 
56 }
57 
58 
59 int main(){
60     linklist head;
61     InitList(head);
62     linklist p;
63     int i;
64     p = CreatLinkList(head);
65     Magician(p);
66     printf("按如下顺序排列:\n");
67     for(i = 0; i < Carnumber; i++){
68         printf("黑桃%d ",p->data);
69         p = p->next;
70     }
71     return 0;
72 } 

运行结果:

猜你喜欢

转载自www.cnblogs.com/geziyu/p/9904914.html