约瑟夫问题(循环链表)

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

输入:n, k, m

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

非法输入的对应输出如下

a)

输入::nkm任一个小于1
输出:n,m,k must bigger than 0.

b)

输入:k>n

输出:k should not bigger than n.

 

例:

输入:9,3,2

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

 测试输入关于“测试输入”的帮助期待的输出关于“期待的输出”的帮助时间限制关于“时间限制”的帮助内存限制关于“内存限制”的帮助额外进程关于“{$a} 个额外进程”的帮助
测试用例 1以文本方式显示
  1. 9,3,2↵
以文本方式显示
  1. 4 6 8 1 3 7 2 9 5↵
1秒64M0
测试用例 2以文本方式显示
  1. 10,12,3↵
以文本方式显示
  1. k should not bigger than n.↵
1秒64M0

 

#include <stdio.h>  
#include <stdlib.h>  
struct node  
{  
    int banngou;  //番号
    struct node* next;   
};  
typedef struct node human;  
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;  
        }  
        human *head,*p,*out;  
        head=(human*)malloc(sizeof(human));  
        head->banngou=-1;  
        head->next=head;  //建立循环空表  
        for(i=n;i>0;i--)  //插入全部结点
        {  
            p=(human*)malloc(sizeof(human));  
            p->next=head->next;  
            p->banngou=i;  
            head->next=p;  
         }   
        while(p->next!=head) //使p为head前一个结点  
        p=p->next;  
        p->next=head->next; //形成抛弃head的循环链表  
        p=p->next; //此时p为第一个结点   
        for(i=0;i<k-2;i++) p=p->next; //此时p为第k-1个结点  
        for(j=1;j<n+1;j++)  
        {  
            for(l=0;l<m-1;l++) p=p->next; //此时p为报m-1的结点   
            out=p->next; //标记要出列的结点(报m的结点)   
            p->next=out->next; //跳过要出列的结点  
            printf("%d",out->banngou);  
            free(out);  
            if((j==n)||(j%10==0)) printf("\n");  
            else printf(" ");  
        }  
        break;  
    }  
    return 0;  
      
 }  

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值