首页 > 代码库 > 魔术师发牌和拉丁方阵

魔术师发牌和拉丁方阵

本文利用经典的魔术师发牌问题与拉丁法阵分别讲解了循环链表与单向链表的使用,作为算法中的经典,对于链表的学习和理解都有着很大的帮助,不妨一看。


魔术师发牌问题

问题描述:

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

问题:牌的开始顺序是如何安排的?

经典循环链表问题,代码如下:

#include<iostream>
using namespace std;
#define CardNumber 13
struct node
{
	int data;
	struct node *next;
}*linklist;
void CreateLinkList()
{
	linklist = NULL;
	node *p,*q;
	int i;
	p=linklist;
	for(i=0;i<CardNumber;i++)
	{
		p=new node;
		p->data=http://www.mamicode.com/0;>

拉丁方阵问题

 问题描述:

拉丁方阵是一种n×n的方阵,方阵中恰有n种不同的元素,每种元素恰有n个,并且每种元素在一行和一列中 恰好出现一次。

著名数学家和物理学家欧拉使用拉丁字母来作为拉丁方阵里元素的符号,拉丁方阵因此而得名。

例如:

1      2      3

2      3      1

3      1      2

问题:如何构造N阶拉丁方阵?普通代码如下:(N阶所有拉丁方阵)

#include<iostream>
using namespace std;
#define N 3 /*确定N值*/
int main()
{
	int i,j,k,t;
	printf("The possble Latin Squares of order %d are:\n",N);
	for(j=0;j<N;j++) /*构造N个不同的拉丁方阵*/
	{
		for(i=0;i<N;i++)
		{
			t=(i+j)%N; /*确定该拉丁方阵第i 行的第一个元素的值*/
			for(k=0;k<N;k++) /*按照环的形式输出该行中的各个元素*/
				cout<<(k+t)%N+1;
			cout<<endl;
		}
		printf("\n");
	}
}

单链表实现代码:(拉丁方阵的标准型,其它类型可用类似的单链表方法得到)

#include <stdio.h>
#include <stdlib.h>

typedef struct node
{
        int data;
        struct node *next;
}linklist;

linklist *CreateList(int n);


//创建链表
linklist *CreateList(int n)
{
        linklist *head, *s, *r;
        head = NULL;
        r = head;
        
        for (int i = 1; i <= n; i++)
        {
                s = (linklist *)malloc(sizeof(node));
                s->data = http://www.mamicode.com/i;>