zoukankan      html  css  js  c++  java
  • 算法之美--4.3.4 魔术师发牌问题

     问题描写叙述:

           魔术师手中有A、2、3……J、Q、K十三张黑桃扑克牌。在表演魔术前,魔术师已经将他们依照一定的顺序叠放好(有花色的一面朝下)。魔术表演过程为:一開始,魔术师数1,然后把最上面的那张牌翻过来,是黑桃A;然后将其放到桌面上;第二次,魔术师数1、2;将第一张牌放到这些牌的最以下,将第二张牌翻转过来,正好是黑桃2;第三次,魔术师数1、2、3;将第1、2张牌依次放到这些牌的最以下,将第三张牌翻过来正好是黑桃3;……直到将全部的牌都翻出来为止。问原来牌的顺序是怎样的。

    /*!
     * file 算法之美--4.3.4 魔术师发牌问题.cpp
     * date 2017/02/25 15:58
     *
     * author ranjiewen
     *
     * rief 问题描写叙述:
                 魔术师手中有A、2、3……J、Q、K十三张黑桃扑克牌。在表演魔术前,魔术师已经将他们依照一定的顺序叠放好(有花色的一面朝下)。
                 魔术表演过程为:一開始,魔术师数1,然后把最上面的那张牌翻过来,是黑桃A;然后将其放到桌面上;第二次,魔术师数1、2;
                 将第一张牌放到这些牌的最以下,将第二张牌翻转过来,正好是黑桃2;第三次,魔术师数1、2、3;将第1、2张牌依次放到这些牌的最以下,将第三张牌翻过来正好是黑桃3;
                 ……直到将全部的牌都翻出来为止。问原来牌的顺序是怎样的。
     *
     * TODO: long description
     *
     * 
    ote
    */
    
    #include <iostream>
    using namespace std;
    
    #define N 13
    
    typedef struct Node
    {
        int data;
        Node* pNext;
        Node(int data_ = 0, Node* pNext_ = nullptr) :data(data_), pNext(pNext_){}
    }Node,*LinkList;
    
    
    
    
    void InitLinkList(LinkList&L,int n) //创建并初始化循环链表,L表示表头节点,n创建节点元素的个数
    {
        L = (Node*)malloc(sizeof(Node));
        L->pNext = L; //头结点循环
        LinkList p;
        for (int j = 0; j < n; j++)  //一直在头结点插入
        {
            p = (Node*)malloc(sizeof(Node));
            p->data = 0;
            p->pNext = L->pNext;//插入节点指向头结点
            L->pNext = p; //头结点指向新的节点
        }
        return;
    }
    
    void Magician(LinkList& L, int n) //魔术师问题求解
    {
        LinkList p = L->pNext;
        p->data = 1;//第一张为1;
        for (int num = 2; num <= n;num++) //依次找到2-n牌的位置
        {
            int i = 0;
            while (i<num)
            {
                p = p->pNext;
                if (p->data==0) //跳过有牌的位置,没有牌的才加1
                {
                    i++;
                }
            }
            p->data = num;
        }
    }
    
    void Print(LinkList&L)
    {
        LinkList p = L->pNext;
        cout << "Print:";
        while (p!=L)
        {
            cout << p->data << " ";
            p = p->pNext;
        }
        cout << endl;
    }
    
    int main()
    {
        LinkList L;
        InitLinkList(L,N);
        Magician(L,N);
        Print(L);
        return 0;
    }

    通过约瑟夫环和魔术师发牌问题:对基本的链表操作熟悉下了,特别是创建过程,对于循环链表;循环的方式可以把头结点放在里面(本题),也可以不放在里面(约瑟夫问题),通过内存可以查看;两种方式判断循环结束的方式也有差别。

    CirSinglist *p;
    p = pHead->pNext;
    while (p->pNext!=p)  (不带头结点)

    LinkList p = L->pNext;
    cout << "Print:";
    while (p!=L)(带头结点)

    魔术师发牌问题

    c语言魔术师发牌问题(循环链表)

     

     

  • 相关阅读:
    c++ CPO ADL
    c++ intrusive
    c++边界检查
    C++仿函数
    C++ RefBase
    c++ vector容器的尺寸问题
    关于调用约定
    C++学习之字符串类、容器
    C++异常
    Git常用命令大全,迅速提升你的Git水平
  • 原文地址:https://www.cnblogs.com/ranjiewen/p/6439667.html
Copyright © 2011-2022 走看看