百练_2746约瑟夫问题

约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环。又称“丢手绢问题”.)


问题:设编号为1,2,...,n的n个人按顺时针方向坐成一排,每个人都有一个正整数密码,开始时任意选一个正整数m(m<n),从第一个人开始按顺时针方向自1起顺序报数,报到m时停止报数,报到m的人出列,其他的密码作为新的m值,从他在顺时针方向上的下一个人起重新从1开始报数,如此下去,直到所有的人全部出列为止。


思路:用顺序存储结构存储每个人的编号,定义一个数组a,数组元素从0开始,所以初始时a[i]存放人的编号为i+1,用计数器count来表示每个人报到的编号,当count==m时,报到count的元素编号变为0表示出列,用d表示出列人数,当d==n的时候结束循环


输入:10, 4


输出:4,8,2,7,3,10,9,1,6,5

#include<stdio.h> 
int main()  
{  
    int m,n,i,d=0,count=0; //d控制出列的个数   
    int a[255];  
    scanf("%d%d",&n,&m);  
      
    for(i=0;i<n;i++)  
    a[i]=i+1;             //给a赋初始值   
       
    while(d<n)  
    for(i=0;i<n;i++)  
    if(a[i]!=0)  
    {  
        count++;          //计数器开始从0报数   
        if(count==m)      //报数到m的人出列   
        {  
            printf("%d ",a[i]);  
            a[i]=0;                    
            count=0;      //从出列的下一位人继续从0开始报数   
            d++;  
        }  
    }   
       
    return 0; 
}

子问题:猴子选王

问题:一堆猴子都有编号,编号是1,2,3 ...m,这群猴子(m个)按照1-m的顺序围坐一圈,从第1开始数,每数到第N个,该猴子就要离开此圈,这样依次下来,直到圈中只剩下最后一只猴子,则该猴子为大王。

思路:要找到哪只猴子是大王就是为了找到最后一个出列的元素,这时和上面的思路一样,我们只需要用一个if语句来控制程序打印出最后一个元素便可以解决了

输入:10,4

输出:5
#include<stdio.h>
int main()  
{  
    int m,n,i,d=0,count=0;   
    int a[255];  
    scanf("%d%d",&n,&m);  
      
    for(i=0;i<n;i++)  
    a[i]=i+1;              
       
    while(d<n)  
    for(i=0;i<n;i++)  
    if(a[i]!=0)  
    {  
        count++;            
        if(count==m)         
        {  
          if(d==n-1)    printf("%d",a[i]);//当d为最后一个元素出列的时候打印出该值   
            a[i]=0;                    
            count=0;        
            d++;  
        }  
    }   
       
    return 0; 
} 

总的来说,约瑟夫问题并不难,但求解的方法很多;题目的变化形式也很多,我们用可以用一个循环的链表来表示,也可以使用结构数组来构成一个循环链,本文章用的就是结构数组来构成循环链。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值