魔术师发牌问题
问题描述:
魔术师利用一副牌中的13张黑牌,预先将他们排好后叠放在一起,牌面朝下。对观众说:“我不看牌,只数数就可以猜到每张牌是什么,我大声数数,你们听,不信?现场演示。”魔术师将最上面的那张牌数为1,把他翻过来正好是黑桃A,将黑桃A放在桌子上,第二次数1,2,将第一张牌放在这些牌的下面,将第二张牌翻过来,正好是黑桃2,也将它放在桌子上这样依次进行将13张牌全部翻出,准确无误。
问题:牌的开始顺序是如何安排的?
请利用循环链表来解决
#include <stdio.h>
#include <stdlib.h>
#define CardNumber 13
typedef struct node
{
int data;
struct node *next;
}sqlist, *linklist;
linklist CreateLinkList()
{
linklist head = NULL;
linklist s, r;
int i;
r = head;
for(i=1; i <= CardNumber; i++)
{
s = (linklist)malloc(sizeof(sqlist));
s->data = 0;
if(head == NULL)
head = s;
else
r->next = s;
r = s;
}
r->next = head;
return head;
}
// 发牌顺序计算
void Magician(linklist head)
{
linklist p;
int j;
int Countnumber = 2;
p = head;
p->data = 1; //第一张牌放1
while(1)
{
for(j=0; j < Countnumber; j++)
{
p = p->next;
if(p->data != 0) //该位置有牌的话,则下一个位置,说明这张牌已经被拿出去了
{
p->next;
j--;
}
}
if(p->data == 0)
{
p->data = Countnumber;
Countnumber ++;
if(Countnumber == 14)
break;
}
}
}
// 销毁工作
void DestoryList(linklist* list);
int main()
{
linklist p;
int i;
p = CreateLinkList();
Magician(p);
printf("按如下顺序排列:\n");
for (i=0; i < CardNumber; i++)
{
printf("黑桃%d ", p->data);
p = p->next;
}
DestoryList(&p);
return 0;
}
另一种实现:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
const int cardNumber=13;
typedef struct Node
{
int data;
Node *next;
}node;
void CreateList(node **pHead)
{
if((*pHead)==NULL)//表头元素
{
(*pHead)=(node*)malloc(sizeof(node));
(*pHead)->data=0;
(*pHead)->next=(*pHead);
}
node *cur=(*pHead);
for(int i=1;i<cardNumber;i++)
{
node *tmp=(node*)malloc(sizeof(node));
tmp->data=0;
tmp->next=(*pHead);
cur->next=tmp;
cur=tmp;
}
}
void MagicCard(node **pHead)
{
(*pHead)->data=1;
node *cur=(*pHead)->next;
for(int i=2;i<=cardNumber;i++)
{
int j=1;
while(j<i)
{
if(cur->data==0)
{
j++;
}
cur=cur->next;
}
while(cur->data!=0)
cur=cur->next;
cur->data=i;
}
}
void Print(node *pHead)
{
node *cur=pHead;
for(int i=1;i<=cardNumber;i++)
{
printf("第%d张牌放的是:黑桃%d\n",i,cur->data);
cur=cur->next;
}
}
void DestroyList(node *pHead)
{
node *s=pHead;
int i=cardNumber;
while(--i)
{
node *tmp=s;
s=s->next;
free(tmp);
tmp=NULL;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
node *pHead=NULL;
CreateList(&pHead);
MagicCard(&pHead);
Print(pHead);
DestroyList(pHead);
system("pause");
return 0;
}
拉丁方阵问题
拉丁方阵是一种n×n的方阵,方阵中恰有n种不同的元素,每种元素恰有n个,并且每种元素在一行和一列中 恰好出现一次。
著名数学家和物理学家欧拉使用拉丁字母来作为拉丁方阵里元素的符号,拉丁方阵因此而得名。
例如下图是一个3×3的拉丁方阵: