基础——约瑟夫环

8 篇文章 0 订阅
2 篇文章 0 订阅

约瑟夫环问题:一圈共有N个人,从1开始报数,报到M的人OUT,然后重新开始报数,问最后OUT的人是谁?【N=10,M=3】

/*
    ①数组:遇到一次m count+1 直到count=n  结束 / 循环n-1次 不用count计算
        / 从后往前推:
        》j = 0for i 从 2 到 n:
        》》j = (m+j)%i
        》》最终第j个人会留下来(如果从1开始编号就是第j+1个人最终会留下来。
*/
/*

    ②**递推思想:递推公式:可以用一个式子来表示数列{an}的第n项与它前一项或几项的关系
**找规律**
    当有n个人时,变成一个子问题 (n-1)个人的报数问题,编号依次为0 1 2 3 ... n-1 ,求最后一轮的人在第一轮中的编号。【对于最后一轮来说,最后留下来的人正是最后一轮开始报数的人。我们只需要求出相邻的两轮之间,同一个人在后一轮的编号和在前一轮里的编号,那么就可以求出来这个人在倒数第二轮里的编号,求出倒数第二轮的对应编号,那么这个人对应在倒数第三轮的也能求出……直到对应到第一轮。】

例:n=5 m=5
每一轮编号都从开始报数的那个人开始算,那么第二轮出列的人在第二轮的编号是(m-1)%(n-1),在第一轮编号为[m + (m - 1) % (n-1)]%n。剩下各轮也是这样。


编号:  0 1 2 3 4      
报数人:1 2 3 4 55人 第一轮:报数为m的人编号为(m-1)%n,出列;
       1 2 3 44人 第二轮:有n - 1个人,编号为(m+0)%n的开始报数
       2 3 432 4241人


so此轮编号为(m+i)%n的人将做为下一轮编号为i的人;
编号为F(n-1)的人肯定对应着上一轮的F(n) 所以有 
    F[n]=(F[n-1]+m)%n (n>1) 【F[1]=0 :剩最后一个人 此人编号为0】

**[补充知识]**求余、取模 区分
ex:4/3=1.3
    求余 4/(-3)=1  商值向0方向舍弃小数位 4rem -3=1
    取模 4/(-3)=2  商值向0方向舍弃小数位为 4mod -3=-2
    唯一的区别在于: 当x和y的正负号一样的时候,两个函数结果是等同的;当x和y的符号不同时,rem函数结果的符号和x的一样,而mod和y一样。
*/

#include<stdio.h>
int main()
{
    int n,m;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        int i,result=0;
        for(i=2;i<=n;i++)
            result=(result+m)%i;
        printf("%d\n",result+1);
    }
    return 0;
}
/*
    ③单向循环链表
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值