循环队列之约瑟夫环问题
约瑟夫问题
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后 结果+1即为原问题的解。
循环队列求解(链式)
#include<stdio.h> #include<stdlib.h> //循环队列 //typedef int ElemType; typedef struct QueueNode { int data; struct QueueNode *next; }QueueNode; typedef struct Queue { QueueNode *front; QueueNode *rear; }Queue; void InitQueue(Queue *q) { q->front=q->rear=NULL; } void EnQueue(Queue *q , int value) { QueueNode *temp=(QueueNode*)malloc(sizeof(QueueNode)); temp->data=value; if(q->rear==NULL) { temp->next=temp; q->rear=q->front=temp; } else { temp->next=q->rear->next; q->rear->next=temp; q->rear=temp; } }//enter a element from the tail void DeQueue(Queue *q, int *value) { QueueNode *temp=(QueueNode*)malloc(sizeof(QueueNode)); if(q->rear==NULL) { return; }// It's null else if(q->rear->next==q->rear) { *value=q->front->data; free(q->rear); q->rear=q->front=NULL; }//It just has one node else { *value=q->front->data; temp=q->front; q->front=temp->next; q->rear->next=q->front; }//more one node free(temp); }//delete a element from the head int main() { Queue *q=(Queue*)malloc(sizeof(Queue)); int i,m,n,count,temp; printf("请输入人数n和循环要报的数m(两数之间留个空格)\n"); scanf("%d%d",&n,&m); for(i=1;i<=n;i++) EnQueue(q,i); printf("出圈序列:\n"); while(q->front) { count=1; while(count<m) { q->front=q->front->next; q->rear=q->rear->next; count++; } count=1; DeQueue(q,&temp); printf("%d ",temp); } putchar('\n'); }
简单解法
#include <stdio.h> int josephus(int n, int m) { if(n == 1) { return 0; } else { return (josephus(n-1, m) + m) % n; } } int main() { int n, m; while (scanf("%d", &n) == 1) { if (!n) { break; } scanf("%d", &m); int result = josephus(n, m); printf("%d\n", result+1); } return 0; }