Problem Description
(本题要求用循环链表实现)
约瑟夫问题是一个经典的问题。已知n个人(不妨分别以编号1,2,3,...,n 代表)围坐在一张圆桌周围,从编号为 k 的人开始,从1开始顺时针报数1, 2, 3, ...,顺时针数到m 的那个人,出列并输出。然后从出列的下一个人开始,从1开始继续顺时针报数,数到m的那个人,出列并输出,...依此重复下去,直到圆桌周围的人全部出列。
输入:n,k,m
输出:按照出列的顺序依次输出出列人的编号,编号中间相隔一个空格,每10个编号为一行。
非法输入的对应输出如下
a)
输入:n、k、m任一个小于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
AcCode
// main.cpp
// 约瑟夫问题
//
// Created by jetviper on 2017/3/26.
// Copyright © 2017年 jetviper. All rights reserved.
//
#include "stdio.h"
#include "stdlib.h"
#include "stdlib.h"
#include "math.h"
#define LEN sizeof(struct linklist)
typedef struct linklist
{
int num;
struct linklist *next;
}list;
struct linklist * create_list(int n)
{
list *head;
list *p1, *p2;
head = (struct linklist *)malloc(LEN);
p2 = head;
p2->next = NULL;
p1 = NULL;
for (int i = 1; i <= n; i++)
{
p1 = (struct linklist *)malloc(LEN);
p1->num = i;
p2->next = p1;
p2 = p1;
p1->next = NULL;
}
p1->next = head->next;
return head;
}
void serch(struct linklist *head, int n, int k,int m)
{
list *p1, *p2;
p1 = head->next;
p2 = NULL;
list *temp;
while (1) {
if (p1->num != k) {
p1 = p1->next;
continue;
}
else break;
}
int cout=1;
for (int i = 0; i < n; i++)
{
for (int j = 1; j < m; j++)
{
p2 = p1;
p1 = p1->next;
}
if (i == n - 1) {
printf("%d\n", p1->num);
cout++;
}
else if (cout == 10) {
printf("%d\n", p1->num);
cout = 1;
}
else {
printf("%d ", p1->num);
cout++;
}
temp = p1;
p2->next = temp->next;
p1 = temp->next;
free(temp);
}
}
int main()
{
int n,k,m;
list *head;
scanf("%d,%d,%d", &n,&k, &m);
if (n < 1 || k < 1 || m < 1) {
printf("n,m,k must bigger than 0.\n");
return 0;
}
if (k>n) {
printf("k should not bigger than n.\n");
return 0;
}
head = create_list(n);
serch(head, n,k, m);
}
网友评论