约瑟夫问题(循环链表)

第一次写这道题时用了几个变量一头扎进去就开始模拟,感觉挺有意思(擦汗)。

出圈

时间限制: 1 Sec | 内存限制: 128 MB
描述:

设有n个人围坐一圈并按顺时针方向从1到n编号,从第1个人开始进行1到m的报数,报数到第个m人,此人出圈,再从他的下一个人重新开始1到m的报数,如此进行下去直到所剩下一人为止。
输入
输入多行,每行2个数,分别表示n和m.
输出
计算每一行中最后剩下这个人的编号.
样例输入
10 3
样例输出
4

现在刚学会线性表一点皮毛,突然想到了约瑟夫,我天!这题和循环链表简直是天作之合啊。

算法

1.用尾插法建立一个循环链表,依次存入从1到n的编号。
2.从第一个结点开始报数,报数的结点被删除然后释放内存就可以了呀。
代码如下

#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
typedef struct node{
	int data;
	struct node *next;
}node;
typedef struct node LNode, *LinkList;
void CreateList_T(LinkList head, int n){
	LinkList p, rear=head;
	int num;
	for(int i=0; i<n; i++)
	{
		p=(LinkList)malloc(sizeof(LNode));
		p->data=i+1; 		//编号 
		rear->next=p;
		rear=p;
	 } 
	 rear->next=head->next; 
} 
int main()
{
	LinkList head;
	int i, e, select, m, k;
	while(scanf("%d%d", &m, &k)!=EOF) 
	{
		if(k==1)
			printf("%d\n", m);
		else
		{
			head=(LinkList)malloc(sizeof(LNode));
			head->next=NULL;
			CreateList_T(head, m);
			LNode *p=head, *temp;
			while(p!=p->next)
			{
				for(i=1; i<k; i++)		//报数 
				{
					p=p->next;
				}
				temp=p->next;			//删除结点 
				p->next=temp->next;
				free(temp);
			}
			printf("%d\n",p->data);				
		}
	}

	return 0;
}

然而
这个代码写得并不太好,我刚开始提交上去毫无疑问肯定是WA啊,找了半天才发现当出圈报数k=1时程序把所有人都划出圈了。
所以就有了上面的程序,把k=1的情况特殊处理,不过应该有还有更好的优化方式(除了特殊处理),先不管吧,AC了就睡觉。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值