1. 约瑟夫问题

文章目录

  • 问题描述
  • 测试用例
  • 代码
  • 思路


问题描述

约瑟夫问题是一个经典的问题。已知 n 个人(不妨分别以编号 1,2 ,3,…,n 代表 )围坐在一张圆桌周围,从编号为 k 的人开始,从1开始顺时针报数 1, 2, 3, ...,顺时针数到m 的那个人,出列并输出。然后从出列的下一个人开始,从1开始继续顺时针报数,数到 m的那个人,出列并输出,…依此重复下去,直到圆桌周围的人全部出列。

输入:n, k, m

输出:按照出列的顺序依次输出出列人的编号,编号中间相隔一个空格,每10个编号为一行。


测试用例

测试输入期待结果
测试用例 19,3,24 6 8 1 3 7 2 9 5
测试用例 210,12,3k should not bigger than n.

代码

#include <stdio.h>    
#include <stdlib.h>    
struct node   
{    
    int x;  
    struct node* next;     
};    
int main()    
{    
    int n,k,m;    
    int i,j,l;     
    scanf("%d,%d,%d",&n,&k,&m);    
    while(1)    
    {    
        if(n<1||k<1||m<1)    
        {    
            printf("n,m,k must bigger than 0.\n");    
            break;    
        }    
        if(k>n)    
        {    
            printf("k should not bigger than n.\n");    
            break;    
        }    
        struct node *head,*p,*out;    
        head=(struct node*)malloc(sizeof(struct node));    
        head->x=-1;    
        head->next=head;     
        for(i=n;i>0;i--)  
        {    
            p=(struct node*)malloc(sizeof(struct node));    
            p->next=head->next;    
            p->x=i;    
            head->next=p;    
         }     
        while(p->next!=head)   
        {  
            p=p->next;   
        }   
        p->next=head->next;   
        p=p->next;     
        for(i=0;i<k-2;i++) p=p->next;    
        for(j=1;j<=n;j++)    
        {    
            for(l=0;l<m-1;l++) p=p->next;    
            out=p->next;     
            p->next=out->next;   
            printf("%d",out->x);    
            free(out);    
            if((j==n)||(j%10==0))   
            printf("\n");    
            else   
            printf(" ");    
        }    
        break;    
    }    
    return 0;    
        
 }  

思路

创建一个循环单链表,然后从head开始寻找第m个人,即每次走m-1次,找到m的节点,输出m后将其从链表中删除。重复执行以上操作直到链表中只剩head节点。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值