算法题:约瑟夫环问题

原题:

N个人围成一圈顺序编号,从1号开始按1、2、3…顺序报数,报p者退出圈外,其余的人再从1、2、3开始报数,报p的人再退出圈外,以此类推。 请按退出顺序输出每个退出人的原序号。

输入格式:

输入只有一行,包括一个整数N(1<=N<=3000)及一个整数p(1<=p<=5000)。
输出格式:
按退出顺序输出每个退出人的原序号,数据间以一个空格分隔,但行尾无空格。

输入样例:
7 3
输出样例:
3 6 2 7 5 1 4

实现

使用单向循环链表解决这个问题。

#include <stdio.h>
#include <stdlib.h>

typedef struct node{
   int date;
   struct node *next;
}node,*cmd;     //创建链表

cmd create();   //创建函数
void print(cmd L);  //输出函数
int a,b;        //一共a个数,报b则出链

int main()
{
   cmd L;
   scanf("%d %d",&a,&b);
   L=create();
   print(L);
   return 0;
}

cmd create()   // 创建含有 1 2 3....a个数的链表
{
   int i;
   cmd L,p,s;
   L=(cmd)malloc(sizeof(node));
   p=L;
   p->date=1;
   for(i=2;i<=a;i++){   
   s=(cmd)malloc(sizeof(node));
   s->date=i;
   p->next=s;
   p=s;
 }
    p->next=L;    //循环链表
    return L;
}

void print(cmd L)
{
   int i=0,j,r[1000];   //数组存放出列数字
   cmd q,p;      //删除链结点所需
   p=L;           
   while(i<a){  
      for(j=1;j<(b-1);j++){   //将目标停在要报b
        p=p->next;}              的前一个结点
      q=p->next;         //做删除结点
      r[i]=q->date;      //出链的结点date保存到
      p->next=q->next;     数组里
      free(q);
      p=p->next;
      i++;
 }
 for(j=0;j<=a-1;j++)
  printf("%d ",r[j]);
}

参考

https://blog.csdn.net/qq_44797278/article/details/105616189?spm=1001.2101.3001.6650.7&utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~Rate-7-105616189-blog-122014339.235^v38^pc_relevant_anti_t3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~Rate-7-105616189-blog-122014339.235^v38^pc_relevant_anti_t3&utm_relevant_index=12

posted @ 2023-11-13 16:08  爱吃砂糖橘的白龙  阅读(26)  评论(0编辑  收藏  举报