C语言 人环游戏

不知道大家是否还记得这样一个游戏,一群人,手拉手站成一个环,从第一个人开始报数,可以以三个数为一轮,也就是1,2,3,1,2,3......这样去报,喊到3的人淘汰,其左右两个人再手拉着手,游戏继续进行。就这样一直下去,直到最后只剩一个人,那个人即为胜者。

其实现实生活中好像根本没人玩这个游戏,但是C语言老师上课提到了这么一个问题,是在讲链表的时候。事实上,在总人数和报数确定了之后,剩下的那个人是几号其实已经产生了,比如说,16个人,三个数为一轮,那么最后剩下的肯定是8号。虽然没什么现实意义,但是作为学者来讲,还是个练习数据结构的好机会,所以我把这个题记录下来。

算法非常的简单,就是一个首尾相接的链表,也就是环链表。当初始化给每一个附上数值之后,就可以用一个while函数加上一个if语句进行淘汰。但是要注意的是,整个游戏结束的标志是只剩一个节点,但此时还是一个环,所以也就是该节点的下一个节点是它本身。

我写的程序中,是在预编译中将人数设置为了50,还是三个数为一轮,具体代码如下(C语言):

#include<stdlib.h>
#include<stdio.h>
#define M 50
#define N 3
struct node{
	int num;
	struct node* next;
};

struct node*init(struct node *head){//构造函数
/*返回的是与节点相同类型的指针*/ 
	struct node *p, *q;
	int i;
	p = (struct node *)malloc(sizeof(struct node));
	p->num = 1;
	head = p;
	for (i = 2; i < M; i++){
		q = (struct node *)malloc(sizeof(struct node));
		p->next = q;
		q->num = i;
		p = q;
	}
	q = (struct node *)malloc(sizeof(struct node));
	p->next = q;
	q->num = M;
	q->next = head;//如果此值为null则为单链表,若为head 则为环

	return head;
}

void print(struct node*head)/*出以head为头的链表各节点的值*/
{
	struct node *temp;
	temp = head;/*取得链表的头指针*/
	while (temp != NULL)/*只要是非空表*/
	{
		printf("%6d", temp->num);/*输出链表节点的值*/
		temp = temp->next;/*跟踪链表增长*/
	}
}

struct node*elim(struct node *head){//淘汰函数
	struct node *p, *q;
	p = head;
	q = p->next;
	int count = 1;//count用来记录报号
	while (q->next != q){
		count++;
		if (count == N){//如果报号为N,则删除该节点
			p->next = q->next;
			q = p->next;
			count = 1;
		}
		p = q;
		q = q->next;
	}

	return q;
}

void main(){
	struct node *head = NULL;//创建单链表
	head = init(head);//创建单链表,环
//	print(head);//打印输出
	struct node *remain = elim(head);
	printf("%d", remain->num);
	system("pause");
}
最终输出的结果是11。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值