N只猴子选大王(用模拟过程的方法解决)

本文详细介绍了如何通过约瑟夫环问题解决猴子报数选出大王的问题,包括使用双向链表进行数据结构设计、生成初始数据以及模拟猴子退出并最终选出大王的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

N只猴子,围成一圈,从1开始报数,数到M的猴子退出,最后剩下一只猴子就选为大王。

此题是约瑟夫环问题,可以推导出公式答案。不过,也可以用模拟过程的方法来解决。

首先定义猴子结点类型:

typedef struct st_Monkey
{
    int SN;
    struct st_Monkey * pNext;
    struct st_Monkey * pPre;
}CMonkey;

为了方便,使用双向链表。

然后读入N和M,生成N只猴子围成一圈的初始数据。

CMonkey * InitMonkeys(int N)
{
    int i=0;
    if(N>0)
    {
        CMonkey * pHead, *pCur;
        for(i=0;i<N;i++)
        {
            if(i==0)
            {
                pCur=(CMonkey*)malloc(sizeof(CMonkey));
                pCur->pNext = NULL;
                pCur->pPre = NULL;
                pHead=pCur;
            }
            else
            {
                pCur->pNext=(CMonkey*)malloc(sizeof(CMonkey));
                (pCur->pNext)->pPre = pCur;
                pCur = pCur->pNext;
                if (i==(N-1))
                {
                    pCur->pNext = pHead;
                    pHead->pPre = pCur;
                }
                else
                {
                    pCur->pNext = NULL;
                }
            }
            pCur->SN = i+1;
        }
        return(pHead);
    }
    else
        return(NULL);
}

模拟选猴王的过程:

CMonkey * ChooseMonkeyKing(CMonkey *pSt, int N, int M)
{
    if(pSt!=NULL)
    {
        int i=1, j=1;
        CMonkey *p0, *p1, *p2;
        p1 = pSt;
        p0 = p1->pPre;
        p2=p1->pNext;
        while(i<N)
        {
            if((j%M)==0)
            {
                printf("\n[del]%d", p1->SN);
                p0->pNext = p1->pNext;
                p2->pPre = p0;
                free(p1);
                p1 = p2;
                p2 = p1->pNext;
                i++; //只有猴子退出,才递增i,这样控制循环执行(N-1)次,最后只剩下一只猴子
            }
            else
            {
                p0 = p1;
                p1 = p2;
                p2 = p2->pNext;
            }
            j++;
        }
        return(p1);
    }
    else
        return(NULL);
}


主函数,没啥好说的了。

int main(void)
{
    int N=0, M=1;
    printf("input N and M(N,M):");
    scanf("%d,%d", &N, &M);
    CMonkey * pHead = InitMonkeys(N);
    CMonkey * pCur = pHead;
    for(int i=1;i<=N;i++)
    {
        printf("SN=%d\t", pCur->SN);
        pCur=pCur->pNext;
    }
    pCur = ChooseMonkeyKing(pHead, N, M);
    if (pCur!=NULL)
       printf("\nThe King is %d.\n", pCur->SN);
    free(pCur);
    printf("\n");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值