算法:约瑟夫环问题

算法:约瑟夫环问题

问题描述

  约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从第一个人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,求最后一个出圈的人的标号。

题目分析

 

C语言实现

void JOSEF(int n,int m) //:n个人,m出列
{
    int people[n+1]; //我们定义的数组大小为n+1,因为我们不想涉及到0的操作,我们只取1到n这个范围内的标号,忽略0
    for(int i=1;i<=n;i++)
        people[i]=i; //将数组内(除0)的每一个元素进行初始化,其实非0即可,值无所谓。
    int flag=n-1;    //我们要在数组里面删除多少个元素呢?答案是n-1个。剩下的一个为最后出圈的那一个
    int p=1;         //用来指示元素下标
    int count=0;     //计数器
    
    while(flag)      //没有删完的情况下继续
    {
        if(people[p]==0)  //如果p所指的元素为0,表示该元素已经出圈,可以跳过
        {
            if(p==n)      //这段代码就是让尾部连接头部
                    p=1;
            else
                    p++;
            continue;
        }
        count++;       //找打一个不为0的元素
        if(count==m)   //如果我们找够m个,就将这个元素出圈,也就是设为0
        {
            people[p]=0;     
            flag--;    //待出圈的元素-1
            count=0;   //重新开始数
        }
        if(p==n)       //这段代码就是让尾部连接头部
            p=1;
        else
            p++;
    }
  
  for(int i=1;i<n;i++)  //那个值不为0元素的下标的就是最后一个出圈的人的序号
  {
    if(people[i]!=0)
    {printf("目标为%d\n",i);break;}
  }

  

 

转载于:https://www.cnblogs.com/MrSaver/p/5926544.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值