问题描述:
魔术师利用一副牌中的13张黑牌,预先将他们排好后叠放在一起,牌面朝下。对观众说:“我不看牌,只数数就可以猜到每张牌是什么,我大声数数,你们听,不信?现场演示。”魔术师将最上面的那张牌数为1,把他翻过来正好是黑桃A,将黑桃A放在桌子上,第二次数1,2,将第一张牌放在这些牌的下面,将第二张牌翻过来,正好是黑桃2,也将它放在桌子上这样依次进行将13张牌全部翻出,准确无误。
解决方案:
用循环链表实现
代码描述:
#include<stdio.h>
#include<stdlib.h>
#define N 13 //魔术师的牌数 (A-K依次用1~13表示)
typedef struct Node
{
int data;
struct Node *next;
}Node;
typedef struct Node *LinkList;
//构造循环链表
Node* CreatList1(struct Node *La,int n)
{
//构造一个循环链表,(结点的值为0)返回循环链表的首地址
int i;
struct Node *p,*s;
La = (LinkList)malloc(sizeof(Node));
La->next = NULL;
p = La;
for(i = 1;i <= N;i++)
{
s = (LinkList)malloc(sizeof(Node));
s->data = 0;
s->next = p->next;
p->next = s;
p = p->next;
}
p->next = La->next;
return p ;
}
//模拟魔术师发牌给链表赋值
Node* magician(struct Node *La,int n) //L->La N->n
{
int i,j,count = 2;//count 用来计数
Node *p,*q;
p = La->next;//p->data == 1
p->data = 1;
for(i = 2;i <= n;i++)
{
for(j = 1;j <= count;j++)
{
p = p->next;
if(p->data != 0)
{
j--;
}
}
p->data = i;
count++;
}
return La->next;
}
int main(int argc,char* argv[])
{
int i;
Node *L,*p,*q;
L = CreatList1(L,N);
L = magician(L,N);//L->La N->n
p = L;
printf("事先牌的排放顺序为:\n");
for(i = 1;i <= N;i++)
{
printf("%3d",p->data);
p = p->next;
}
printf("\n");
system("pause");
return 1;
}
天道酬勤!
浙公网安备 33010602011771号