天天看點

算法之美--4.3.5 拉丁方陣問題

 拉丁方陣問題

問題描寫叙述:

拉丁方陣是一種n×n的方陣,方陣中恰有n種不同的元素,每種元素恰有n個,而且每種元素在一行和一列中 恰好出現一次。

著名數學家和實體學家歐拉使用拉丁字母來作為拉丁方陣裡元素的符号,拉丁方陣是以而得名。

比如:

1 2 3

2 3 1

3 1 2

問題:怎樣構造N階拉丁方陣?

/*!
 * \file 算法之美--4.3.5 拉丁方陣問題.cpp
 *
 * \author ranjiewen
 * \date 2017/02/25 17:02
 *
 * 
 */

/************************************************************************/
/* 拉丁方陣問題
 問題描寫叙述:
 拉丁方陣是一種n×n的方陣,方陣中恰有n種不同的元素,每種元素恰有n個,而且每種元素在一行和一列中 恰好出現一次。
 著名數學家和實體學家歐拉使用拉丁字母來作為拉丁方陣裡元素的符号,拉丁方陣是以而得名。
 比如:
 1      2      3
 2      3      1
 3      1      2
 問題:怎樣構造N階拉丁方陣?                                              */               
/************************************************************************/

////普通代碼,(N階全部拉丁方陣)
//#include <iostream>
//using namespace std;
//
//#define N 6
//int main()
//{
//    int i, j, k, t;
//    printf("The possible 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;
//        }
//        cout << endl;
//    }
//    return 0;
//}

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

typedef struct Node
{
    int data;
    struct Node* pNext;
}Node;

typedef struct Node* LinkList;

//構造一個帶有N個節點的循環連結清單
Node* CreateList(Node* L, int n)
{
    Node *pCur, *pTemp;
    L = (LinkList)malloc(sizeof(Node));
    L->pNext = nullptr;
    pCur = L;//目前節點指向表頭
    for (int i = 1; i <= n;i++)
    {
        pTemp = (LinkList)malloc(sizeof(Node));
        pTemp->data = i;
        pTemp->pNext = pCur->pNext;
        pCur->pNext = pTemp;
        pCur = pTemp;  //在尾部插入
    }
    pCur->pNext = L->pNext; //循環結構
    return L->pNext;
}

//實作拉丁方陣的輸出
void print(struct Node *La, int n)
{
    int i, j;
    struct Node *p, *q;
    p = La;
    for (i = 1; i <= n; i++)
    {
        q = p;
        for (j = 1; j <= n; j++)
        {
            printf("%3d", q->data);
            q = q->pNext;
        }
        printf("\n");
        p = p->pNext;
    }
}

int main(int argc, char* argv[])
{
    int m;
    struct Node *L=nullptr, *t=nullptr;
    //while (1)
    {
        printf("****************************************************\n");
        printf("*****          ESC鍵:    退出程式             *****\n");
        printf("*****                                          *****\n");
        printf("*****          其他任意鍵:列印df拉丁方陣        *****\n");
        printf("****************************************************\n");
        /*    if (_getch() == 27)
                break;
                else*/
        {
            printf("\n請輸入您要列印的拉丁方陣規模(要列印的行數):\n\n");
            scanf("%d", &m);
            L = CreateList(L, m);
            printf("\n您輸入的規模為%d,列印的方陣如下:\n\n", m);
            print(L, m);
            printf("\n請輸入任意鍵繼續:\n");
            _getch();
            system("cls");
        }
    }
    return 0;
}      

魔術師發牌和拉丁方陣

C/C++基本文法學習

STL

C++ primer

繼續閱讀