Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 250|回复: 0

[默认分类] 魔术师发牌问题和拉丁布方阵

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-7-7 12:19:10 | 显示全部楼层 |阅读模式


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


    魔术师发牌问题

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


    #include<iostream>
    using namespace std;
    // 循环链表结构体
    typedef struct _Node
    {
        int data;  // 数据域;
        struct _Node *next;   // 指针域;
    }DNode,*DLinkList;

    // 初始化函数
    void InitDLinkList(DLinkList *pHead)
    {
        *pHead = new DNode;
        (*pHead)->data = 0;
        (*pHead)->next = *pHead;
    }


    // -----------------------------------------魔术师发牌问题--------------------------------

    // 显示发牌顺序
    void ShowMagic(DLinkList pHead)
    {
       
        DLinkList nPos = pHead;
        while (nPos->next!=pHead)
        {
            cout << nPos->data << ",";
            nPos = nPos->next;
            
        }
        cout << nPos->data << endl;
    }

    // 初始化函数
    void MCreate(DLinkList *pHead, int count)
    {
        InitDLinkList(pHead);
        DLinkList nPos = *pHead;
        for (int i = 0; i < count; i++)
        {
            InsertTailDLinkList(pHead, i+1);
        }
        while (nPos->next!=*pHead)
        {
            nPos = nPos->next;
        }
        // 释放头结点
        DLinkList temp = *pHead;
        (*pHead) = temp->next;
        nPos->next =*pHead;
        delete temp;
        temp = NULL;
    }

    // 获取长度
    int GetDLLength(DLinkList pHead)
    {
        int count= 1;
        DLinkList nPos = pHead;
        while (nPos->next!=pHead)
        {
            nPos = nPos->next;
            count++;
        }

        return count;
    }
    // 发牌顺序
    void MSort(DLinkList *pHead)
    {
        int CountNum = 2;   //
        DLinkList nPos = (*pHead);
        nPos->data = 1;
        int len = GetDLLength(*pHead);  // 链表长度
        while (CountNum <=len)
        {
            int i;
            for ( i = 0; i < CountNum; i++)
            {

                    nPos = nPos->next;
                    if (nPos->data != 0)
                    {
                        //    nPos = nPos->next;
                        i--;

                    }
            }
            if (nPos->data==0)
            {
                nPos->data = CountNum;
                CountNum++;
            }

        }
    }


    // 魔术师发牌问题测试程序
    void test()
    {
        DLinkList pHead = NULL;
        int DNodeNum = 0;  // 结点个数
        cout << "请输入结点个数:" << endl;
        cin >> DNodeNum;
        MCreate(&pHead,DNodeNum);
        MSort(&pHead);
        cout << "发牌顺序为:" << endl;
        ShowMagic(pHead);

        DestoryDLinkList(&pHead);
    }

    int main2(void)
    {
        test();
        return 0;
    }




    拉丁方阵问题

      问题描述:
    拉丁方阵是一种n×n的方阵,方阵中恰有n种不同的元素,每种元素恰有n个,并且每种元素在一行和一列中 恰好出现一次。
    著名数学家和物理学家欧拉使用拉丁字母来作为拉丁方阵里元素的符号,拉丁方阵因此而得名。例如:
    1      2      3
    2      3      1
    3      1      2
    问题:如何构造N阶拉丁方阵?普通代码如下:(N阶所有拉丁方阵)

    //----------------------------------------------拉丁布方阵问题----------------------------------



    // 建立方阵函数

    void SetMatrix(DLinkList pHead,int len)

    {



        int count = 0;

        int i, j,k;

        for (i=0;i<len;i++)  // 行

        {

            DLinkList nPos = pHead;

            for (j = 0; j < i; j++)   // 移动结点位置  第 i 行到链表第 i+1 个位置

            {

                nPos = nPos->next;

            }

            for (k = 0; k < len; k++)       //  列输出

            {

                cout << nPos->data << "    ";    // 输出元素

                nPos = nPos->next;

            }

            cout << endl;

        }

    }



    // 拉丁布方阵测试程序

    void test2()

    {

        DLinkList pHead = NULL;

        int arr[3][3] = { 0 };

        cout << "请输入方针的阶数:" << endl;

        int num = 0;

        cin >> num;

        MCreate(&pHead, num);

        SetMatrix(pHead,num);

    }

    int main(void)

    {

        test2();



        return  0;

    }


    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-20 20:40 , Processed in 0.411571 second(s), 37 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表