魔术师发牌问题

来源:互联网 发布:图片尺寸测量软件 编辑:程序博客网 时间:2024/04/25 14:22

魔术师发牌问题

(结束日期2015-11-6-21:45)

问题描述:

魔术师利用一副牌中的13张黑牌,预先将他们拍好后叠放在一起,牌面朝下。对观众说:“我不看牌,只数数就可以猜到每张牌是什么,我大声数数,你们听,不信?现场演示。”魔术师将最上面的那张牌数为1,把他翻过来正好是黑桃A,将黑桃A放在桌子上,第二次数1,2,将第一张牌放在这些牌的下面,将第二张牌翻过来,正好是黑桃2,也将它放在桌子上这样依次进行将13张牌全部翻出,准确无误。

 

1 0 2 0 0 3 0 0 0 4 0 0 0

1 0 2 5 0 3 0 0 0 4 0 0 0

1 0 2 5 0 3 0 0 0 4 0 6 0

1 0 2 5 0 3 0 0 0 4 7 6 0

1 8 2 5 0 3 0 0 0 4 7 6 0

1 8 2 5 0 3 0 0 9 4 7 6 0

1 8 2 5 10 3 0 0 9 4 7 6 0

1 8 2 5 10 3 0 11 9 4 7 6 0

1 8 2 5 10 3 12 11 9 4 7 6 13

 

说明:隔对应数个0放下一数,然后循环隔对应数的0个数,如上表所示。


代码实现:

方法一(基于数组实现):


#include<stdio.h>#include<malloc.h>#include<stdlib.h> typedefstruct magic_poke{         int *pBsae;//定义数组         int cnt;//有效元素个数         int len;//数组长度}Mag,*pMag; boolinit(pMag pMagic_pk);voidmanage_poke(pMag pMagic_pk);voidshow(pMag pMagic_pk);intreturn0_pos(pMag pMagic_pk,int org,int num); intmain(void){         int k=0;         Mag magic;         init(& magic);//      show(& magic); /*     for(int i=0;i<magic.len;i++)         {                   k = return0_pos(&magic,i,15);                   printf("k=%d\n",k);         }        */                        测试返回0的位置          manage_poke(& magic);         show(& magic);                 return 0;} //返回所需求0的个数的最终位置intreturn0_pos(pMag pMagic_pk,int org,int num){                int pos;         int k=0;         int count=0;         pos = org;         pMag pPos = pMagic_pk;         while(1)         {                          pos++;                   if(pos > pPos->len)                   {                            pos = 0;                   }                                   if(0 == pPos->pBsae[pos])                   {                            count++;                   }                                   if(count == num+1)break;                  //其中num+i(数字i代表最开始隔几张牌)         }                   return pos;} boolinit(pMag pMagic_pk){         pMag pMagic = pMagic_pk;         int len;      //定义数组长度         int k;                   //用于接收scanf的返回值         printf("请输入数组的长度len=: ");         k=scanf("%d",&len);         while( !k || len<=0)         {                   printf("您输入有误,请重新输入数组的长度len=: ");                   fflush(stdin);// 清空输入缓存                   k=scanf("%d",&len);         }         int *pNew = (int*)malloc(sizeof(int)*len);         for(int i=0;i<len;i++)         {                   pNew[i]=0;/*               if(i%3 ==0 || i%2 == 0 || i%5 ==0)                   {                            pNew[i]=0;                   }                   else                   {                            pNew[i]=3;                   }                 */         }         pMagic->pBsae = pNew;         pMagic->cnt = 0;         pMagic->len = len;         return true;} voidmanage_poke(pMag pMagic_pk){         pMag pMagic = pMagic_pk;         int k=0;         pMagic->pBsae[0] = 1;         for(int i=1;i<pMagic->len;i++)         {                   k=return0_pos(pMagic,k,i);                   pMagic->pBsae[k]=i+1;         }} voidshow(pMag pMagic_pk){         pMag pMagic = pMagic_pk;         printf("输出的数字为: \n");         for(int i=0;i<pMagic->len;i++)         {                   printf("%d  ",pMagic->pBsae[i]);         }         printf("\n");         return;}

方法二(基于循环链表):

#include<stdio.h>#include<malloc.h>#include<stdlib.h> typedefstruct node{         int data;         struct node *next;}Node,*pNode; pNodeinit_list(pNode pHead,int *len);boolmanagement_list(pNode pHead,int *len);booltraverse_list(pNode pHead); intmain(void){         int length;         pNode pHead = NULL;                                 /*不能用Node pHead; init_list(&pHead);                                                                                     traverse_list(& pHead);因为传递地址已经改变,且不一致*/         pHead = init_list(pHead,& length);         traverse_list(pHead);         management_list(pHead,& length);         traverse_list(pHead);         return 0;} pNodeinit_list(pNode pHead,int *len)                                         /*初始化单向循环链表*/{         pNode pPoke;         int return_val;         printf("请输入链表长度len=: ");         return_val = scanf("%d",len);         while(!return_val || *len <= 0)         {                   printf("输入有误请重新输入链表长度len=: ");                   fflush(stdin);                       //清空输入缓存                   return_val =scanf("%d",len);         }         pNode pNew =(pNode)malloc(sizeof(Node));         if(NULL == pNew)         {                   printf("动态内存分配失败!\n");                   exit(-1);         }         else         {                   pNew->data = 0;                   pHead = pNew;                   pHead->next = pHead;         }         pPoke = pHead;         for(int i=0;i<(*len)-1;i++)         {                   pNode pNew =(pNode)malloc(sizeof(Node));                   if(NULL == pNew)                   {                            printf("动态内存分配失败!\n");                            exit(-1);                   }                   else                   {                            pNew->data = 0;                            pPoke->next =pNew;                            pPoke = pNew;                            pNew->next =pHead;                   }         }         return pHead;} boolmanagement_list(pNode pHead,int *len){         pNode pNext;         pNext = pHead;         int k = 1;         int count;         pNext->data = 1;         while(1)         {                          count = k;                   while(0 != count)               //其中count+i(i表示要隔牌的张数)                   {                            if(0 ==pNext->data)                            {                                     count--;                                     pNext =pNext->next;                            }                            else                            {                                     pNext =pNext->next;                            }                   }                          k++;                   while(0 != pNext->data)                     /* 若无次判断会出现数值覆盖现象 */                   {                            pNext =pNext->next;                   }                   pNext->data = k;                   if(k == (*len))                                         /* 链表完成的终止条件 */                            break;          /*                                                                       //此法写的代码会出现4的倍数无法执行的情况                   for(j=0;j<count;j++)                   {                            pNext =pNext->next;                            if(pNext->data !=0)                            {                                     pNext =pNext->next;                                     j--;                            }                          }                   if(pNext->data == 0)                   {                            pNext->data =count;                            count++;                            if(count == (*len)+1)                                     break;                   }         */          }         return true;} booltraverse_list(pNode pHead){         pNode pNext;         pNext = pHead;         if(pHead == pNext->next)         {                   printf("链表为自身循环链表,不能遍历输出!\n");                   return false;         }         else         {                   printf("%d  ",pNext->data);                   while(pHead !=pNext->next)                   {                            pNext = pNext->next;                            printf("%d  ",pNext->data);                    }                   printf("\n");                   return true;         }}

0 0