zoukankan      html  css  js  c++  java
  • 一个小笔记(3):约瑟夫环

    什么是约瑟夫环?
    其实百度有说
    http://baike.baidu.com/view/717633.htm

    以一个传说中的问题为例子,提供源代码
    主要是能够通过这个问题,了解如何来操作循环链表


    在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏

    最后输出结果为最后一个存活的人的编号

    // 约瑟夫问题(循环链表).cpp
    // Win32控制台程序
    #include "stdafx.h" 
    #include <stdlib.h> 
    
    typedef struct JOSEPH_NODE 
    { 
        int iNum;   // 编号
        struct JOSEPH_NODE * pNext;
    } JOSEPH_NODE_S; 
    
    // pJosephStart结点的下一个结点就是要杀死的人,删除该结点
    void Delete_Next_Joseph(JOSEPH_NODE_S * pJosephStart) 
    { 
        JOSEPH_NODE_S * pJose = pJosephStart->pNext; 
        pJosephStart->pNext = pJose->pNext; 
        free(pJose); 
    } 
    
    // 释放链表
    void Destroy_Joseph(JOSEPH_NODE_S * pJosephHead) 
    { 
        while (pJosephHead->pNext != pJosephHead) 
        {
            Destroy_Joseph(pJosephHead); 
        } 
        free(pJosephHead);
    } 
    
    // 初始化链表
    int Init_Joseph(int iCount, JOSEPH_NODE_S ** ppJosephHead) 
    { 
        if (iCount < 1)
        { 
            return 0; 
        } 
    
        JOSEPH_NODE_S * pJoseNew; 
        JOSEPH_NODE_S * pJoseCur;
        int iSize = sizeof(JOSEPH_NODE_S); 
        pJoseNew = (JOSEPH_NODE_S *)malloc(iSize); 
    
        if (pJoseNew == nullptr) 
        { 
            return 0; 
        } 
    
        pJoseNew->iNum = 1; 
        pJoseNew->pNext = pJoseNew;
        *ppJosephHead = pJoseNew; 
        pJoseCur = pJoseNew; 
     
        // 链表添加结点
        for (int i = 1; i < iCount; i++) 
        { 
            pJoseNew = (JOSEPH_NODE_S *)malloc(iSize); 
    
            if (pJoseNew == nullptr) 
            { 
                Destroy_Joseph(*ppJosephHead); 
                return 0; 
            } 
    
            pJoseNew->iNum = i + 1; 
            pJoseNew->pNext = *ppJosephHead; 
    
            pJoseCur->pNext = pJoseNew; 
            pJoseCur = pJoseNew; 
        } 
    
        return 1;
    } 
    
    // 得到最后一个存活的人
    // iCount:总人数
    // iSkip:每隔多少个人就杀死一个人
    int GetLastNode_Joseph(int iCount, int iSkip) 
    { 
        JOSEPH_NODE_S * pJoseph = nullptr; 
        JOSEPH_NODE_S * pJoseStart = nullptr; 
    
        if (Init_Joseph(iCount, &pJoseph) != 1) 
        { 
            printf("初始化失败
    ");
            return 0; 
        }
        pJoseStart = pJoseph; 
    
        // 每隔0个人杀死,最后一个人存活
        if (iSkip == 0) 
        { 
            while (pJoseStart->pNext->pNext != pJoseStart) 
            { 
                Delete_Next_Joseph(pJoseStart); 
            } 
    
            printf("Final Num: %d
    
    ", pJoseStart->pNext->iNum); 
            free(pJoseStart->pNext); 
            free(pJoseStart); 
    
            return 1; 
        } 
    
        // 每隔iSkip个人杀死一个人
        // 直到剩下1个人,剩下最后一个结点的pNext会指向自己
         while (pJoseStart->pNext != pJoseStart) 
        { 
            for (int i = 1; i < iSkip; i++) 
            { 
                pJoseStart = pJoseStart->pNext; 
            } 
    
            Delete_Next_Joseph(pJoseStart); 
    
            pJoseStart = pJoseStart->pNext; 
        } 
    
        printf("Final Num: %d
    
    ", pJoseStart->iNum); 
    
        free(pJoseStart); 
    
    
        return 1; 
    
    } 
    
    int main() 
    { 
        GetLastNode_Joseph(41, 2); 
    
        return 0; 
    
    }
  • 相关阅读:
    c# Exception 异常信息归整
    解决PKIX(PKIX path building failed) 问题 unable to find valid certification path to requested target
    java Thumbnails 加载网络图片,处理返回base64
    C# 解析 Json
    mysql 中文乱码解决方法
    .Net WinForm下配置Log4Net(总结不输出原因)
    uploadify 后台动态传参数
    C# rename方法重命名文件
    将Qt5.5 动态链接生成的exe及依赖dll打包方法
    远程桌面Default.rdp 中各个参数的含义(转)
  • 原文地址:https://www.cnblogs.com/recordprogram/p/5656736.html
Copyright © 2011-2022 走看看