问题描述
魔术师利用一副牌中的13张黑牌,预先将他们排好后叠放在一起,牌面朝下,对观众说:“我不看牌,只数数就可以猜到每张牌是什么,我大声数数,你们听,不信?现场演示。”魔术师将最上面的那张牌数为1,把他翻过来正好是黑桃A, 将黑桃A放到桌面上,第二次数1,2将第一张牌放在这些牌的下面,将第二张牌翻过来,正好是黑桃2, 也将它放在桌子上这样依次进行将13张牌全部翻出,准确无误。
问题:牌的开始顺序是如何安排的?
代码实现(C语言):
#include<stdafx.h>
#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; //默认所有元素都为0
if (head == NULL)
{
head = s;
}
else
{
r->next = s;
}
r = s;
}
r->next = head;
return head;
}
//发牌顺序计算
void Magician(linklist head) {
linklist p = NULL;
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) {
linklist ptr = *list;
linklist buff[CardNumber];
int i = 0;
while (i < CardNumber)
{
buff[i++] = ptr;
ptr = ptr->next;
}
for (i = 0; i < CardNumber; i++)
{
free(buff[i]);
}
*list = 0;
}
int main() {
linklist p = NULL;
int i;
p = CreateLinkList();
Magician(p);
printf("按如下顺序排列:\n");
for (i = 0; i < CardNumber; i++)
{
p = p->next;
printf("黑桃:%d", p->data);
}
DestoryList(&p);
getchar();
return 0;
}
拉丁方阵问题
拉丁方阵是一种nXn的方阵,方阵中恰有n种不同的元素,每种元素恰有n个,并且每种元素在一行一列中恰好出现一次。著名数学家和物理学家欧拉使用拉丁字母作为拉丁方阵里的元素的符号,拉丁方阵因此而得名。
例如下图是一个3X3的拉丁方阵:
图片.png
问题思路: 采用循环链表,依次输出,每次输出元素后面的3个元素。