/*一日一码08:约瑟夫环问题
已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。
从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列。
求最后出列那个人的编号。
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
} node;
void listMethod(int n, int k, int m){
int i = 0,step = m;
node *head,*p,*q;
p = NULL;
//建立循环队列
head = (node*)malloc(sizeof(node));
q = head;
for (i = 1; i <= n; i++)
{
p = (node*)malloc(sizeof(node));
p->data = i;
q->next = p;
q = q->next;
}
p->next = head->next;
//报数
p = head->next;
while (p->next != NULL && p->next != p)
{
printf("%d号报数!\n", p->data);
step--;
if (step == 0)
{
//出列
printf("本次%d号出局!\n", p->data);
p->data = p->next->data;
q = p->next;
p->next = p->next->next;
free(q);//曾写成free(p->next),这样链表就断啦!
step = m;
}else
{
p = p->next;
}
}
printf("最后剩下%d号!\n", p->data);
}
int next(int arr[],int size,int start, int step, int flag){
int i = 0;
for ( i = start; step > 0; step--) {
if(flag){
printf("%d号报数!\n", i+1);
}
while(-1 == arr[(i + 1)%size]){
i = (i + 1)%size;
}
i = (i + 1)%size;
}
return i;
}
//数组法实现
int arrayMethod(int n, int k, int m){
int i = 0;
int left = n;
int *arr = (int*)malloc(sizeof(int)*n);
//初始化
for (i = 0; i < n; ++i) {
arr[i] = i+1;
}
//i用来表示下一个人
i = 0;
k = k - 1;
//开始报数
while( left > 1){
i = next(arr,n,k,m-1,1);
arr[i] = -1;
//打印每次出局的人
printf("%d号报数!\n本次%d号出局!\n", i+1,i+1);
k = next(arr,n,i,1,0);
left--;
}
i = next(arr,n,k,1,0);
printf("最后剩下%d号!\n", i+1);
return k;
}
int main(int argc, char const *argv[])
{
int n,k,m;
n = 9;
k = 1;
m = 5;
arrayMethod(n,k,m);
listMethod(n,k,m);
return 0;
}
一日一码08——约瑟夫环
最新推荐文章于 2024-10-16 15:40:48 发布