2.约瑟夫问题

来源:互联网 发布:python decorator 编辑:程序博客网 时间:2024/05/29 04:26
约瑟夫问题

     

      (本题要求用循环链表实现)

      

约瑟夫问题是一个经典的问题。已知n个人(不妨分别以编号123,...,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

测试用例1:
输入:9,3,2↵
输出:4 6 8 1 3 7 2 9 5↵
测试用例2:
输入:10,12,3↵
输出:k should not bigger than n.↵

代码如下:
#include<stdio.h>               #include<malloc.h>  #include<stdlib.h>  #define ListSize 100  typedef int DataType;  typedef struct Node  {      DataType data;      struct Node *next;  }ListNode,*LinkList;  /*函数声明*/  LinkList CreateCycList(int n);/*创建一个长度为n的循环单链表的函数声明*/  void Josephus(LinkList head,int n,int m,int k); /*在长度为n的循环单链表中,报数为编号为m的出列*/  void DisplayCycList(LinkList head);/*输出循环单链表*/  int main()  {      LinkList h;      int n,k,m;      scanf("%d,%d,%d",&n,&k,&m);      if(n<1||k<1||m<1)printf("n,m,k must bigger than 0.\n");      else if(k>n)printf("k should not bigger than n.\n");      else      {          h=CreateCycList(n);          Josephus(h,n,m,k);      }      system("pause");      return 0;             }  void Josephus(LinkList head,int n,int m,int k)  /*在长度为n的循环单链表中,从第k个人开始报数,数到m的人出列*/  {      ListNode *p,*q;      int i,j;      p=head;      for(i=1;i<k;i++)     /*从第k个人开始报数*/      {          q=p;          p=p->next;      }      for(j=1;j<=n;j++)      {          if (j==1)j=1;          else if((j-1)%10==0)printf("\n");          else printf(" ");          for(i=1;i<m;i++) /*数到m的人出列*/          {              q=p;              p=p->next;          }          q->next=p->next;  /*将p指向的结点删除,即报数为m的人出列*/          printf("%d",p->data);          free(p);          p=q->next;           /*p指向下一个结点,重新开始报数*/      }      printf("\n",p->data);  }  LinkList CreateCycList(int n)   /*宏定义和单链表类型定义*/  {      LinkList head=NULL;      ListNode *s,*r;      int i;      for(i=1;i<=n;i++)      {          s=(ListNode*)malloc(sizeof(ListNode));          s->data=i;          s->next=NULL;          if(head==NULL)              head=s;          else    r->next=s;          r=s;  }      r->next=head;      return head; }  void DisplayCycList(LinkList head)   /*输出循环链表的每一个元素*/  { ListNode *p;      p=head;      if(p==NULL)      { printf("该链表是空表");          return;  }      while(p->next!=head)   /*如果不是最后一个结点,输出该结点*/      {  printf("%4d",p->data);          p=p->next;  }      printf("%4d\n",p->data);/*输出最后一个结点*/  }



0 0