【数据结构基础】约瑟夫问题

约瑟夫问题(10分)

成绩 10 开启时间 2017年09月27日 星期三 15:10
折扣 0.8 折扣时间 2017年10月20日 星期五 15:10
允许迟交 关闭时间 2018年01月8日 星期一 23:55

约瑟夫问题 

 

成绩10  折扣0.8  

     

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

      

 

约瑟夫问题是一个经典的问题。已知n个人(不妨分别以编号123,…,代表 )围坐在一张圆桌周围,从编号为 k 的人开始,从1开始顺时针报数1, 2, 3, ...,顺时针数到的那个人,出列并输出。然后从出列的下一个人开始,从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 以文本方式显示
  1. 9,3,2↵
以文本方式显示
  1. 4 6 8 1 3 7 2 9 5↵
1秒 64M 0
测试用例 2 以文本方式显示
  1. 10,12,3↵
以文本方式显示
  1. k should not bigger than n.↵
1秒 64M 0

应该是很多的好答案了网上~
这里自己写了一个不太规范的链表,比如第一行开始建立一个循环链表的时候直接把头结点head也用了进来。。看到书上先用头节点建立这个循环链表,倒叙建立,然后再把头尾连起来。
然后这题自己的思路是:
0):建立结构体,element值代表开始的排序号
1):建立循环链表:倒叙把值这些序号输入
2):用一个循环先把第k个人找出来
3):从第k个人开始,建立一个timer,然后数到相应的人就把他输入,然后删除,删除前把前后两个节点连起来。timer归置0
4):到最后一个结束的标志:一个节点前的节点也是自己。然后输出他,结束~
写的略浮肿的程序//不过实现了也很开熏hhhh
#include
#include
int n,m,k;
struct node;
typedef struct node *PtrToNode;
typedef PtrToNode List,Position;
typedef struct node
{
	int element;
	PtrToNode next;	
};
int main()
{
	List head;
	head=(PtrToNode)malloc(sizeof(struct node));
	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;
	}
	int InitialRank=n;
	head->next=head;
	head->element=1;
	while(InitialRank>=2)
	{
		Position temp;
		temp=(PtrToNode)malloc(sizeof(struct node));
		temp->element=InitialRank;
		InitialRank--;
		temp->next=head->next;
		head->next=temp;		
	}//建立初始的圈 
	List P=head;
	while(1)
	{
		if(P->element==k)
		{
			break;
		}
		else
		{
			P=P->next; 
		}
	}//找到编号为k的人开始,他是P;含有潜在bug 
	int times=1;	
	int SumOfPrint=0;
	int RealSum=0;
	Position Pre=head;
	while(Pre->next!=P) 
		Pre=Pre->next;
	while(1)
	{
		if(m==times)
		{
			printf("%d",P->element);
			SumOfPrint++;
			RealSum++; 
			if(SumOfPrint>=10||RealSum==n)
			{
				printf("\n");
				SumOfPrint=0;
			}
			else
			{
				printf(" ");
			}
			if(P==P->next)
			{
				free(P);
				//printf("//");
				return 0;
			} //最后一个数 释放后退出程序 
			Pre->next=P->next;
			free(P);
			P=Pre->next;
			times=1;
			continue; 
		}
		else
		{
			Pre=P;
			P=P->next;
			times++; 
		}	
	}//开始,找到第每个号数的人,然后输出,删除 	
}



你可能感兴趣的:(【数据结构基础】约瑟夫问题)