C语言(经典编程题:报数游戏)

题目描述

有n个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。


题目分析 

 这便是整体的题目流程,大家围成一个圈,愉快的报着数,报到3的人直接out,下一个小伙伴再次从一开始报起,直到我们的决赛圈:

在这也是恭喜我们的m+x号同学获得游戏胜利,可他究竟是谁呢?这也正是我们编程所要解决的目标。 

编程解决

 做这道题的思路其实也正是我们用代码来把整个游戏过程表示出来,让电脑来帮我们依次报数、淘汰、找出决胜者。

接下来是函数原型:

int remind(int n){}   //形参n传入参加此次游戏的总人数,用int返回值来返回胜利者编号

为了解决游戏人数由n传入,存储大小未定的问题我们需要用到C语言动态分配的知识,来定义一个动态数组并且给他们依次赋上编号。 

 而且此题中我们会发现一个关键性的变量,那就是各个玩家所报出来的数字,我们用这个数字来淘汰每个报数报到3的玩家,在这里我们将他命名为tag,同时,我们还需要一个变量来记录淘汰玩家的个数,当淘汰个数到达n-1的时候游戏结束,胜利者也就诞生了,于是我将这个变量命名为out。

int* circle = (int*)malloc(n * sizeof(int));   //生成动态数组来对应每位玩家的状态
int tag = 1;        //当前报数号
int out = 0;        //游戏淘汰人数

for (int i = 1; i <= n; i++)   //为每一位游戏成员挂上编号
	circle[i - 1] = i;

同时,我们需要一个循环来不断地进行报数操作,并且完成每位成员依次报数与报到3即淘汰的操作,循环到淘汰玩家到n-1个时退出循环:

int i = 0;              //用于遍历每一位成员
while (out != n - 1)    //循环到淘汰人数达到n-1人
{
	if (circle[i] == -1)   //如果该成员已被淘汰则不参与计数
	{
		if (i == n - 1)
			i = 0;
		else
			i++;
		continue;
	}
	if (tag == 3)          //如果报数为3,将此成员淘汰,将淘汰人数加1,并且将报数号重置
	{
		circle[i] = -1;    //淘汰则将此成员编号赋为-1以示淘汰
		out++;
		tag = 1;
		if (i == n - 1)
			i = 0;
		else
			i++;
		continue;
	}
	tag++;        //正常(人员未被淘汰参与报数且报数不为3)状况代码段
	if (i == n - 1)
		i = 0;
	else
		i++;
}

对玩家数组的操作已经完毕,接下只需确定返回值内容即可,接下来直接展示完整代码。 

 全部代码

#include<stdlib.h>

int remind(int n)
{
	int* circle = (int*)malloc(n * sizeof(int));
	int tag = 1;
	int out = 0;

	for (int i = 1; i <= n; i++)   //初始化数组
		circle[i - 1] = i;

	int i = 0;             //用于遍历每一位成员
	while (out != n - 1)
	{
        //如果该成员已被淘汰则不参与计数
		if (circle[i] == -1)  
		{
			if (i == n - 1)
				i = 0;
			else
				i++;
			continue;
		}
        //如果报数为3,将此成员淘汰,将淘汰人数加1,并且将报数号重置
		if (tag == 3)     
		{
			circle[i] = -1;
			out++;
			tag = 1;
			if (i == n - 1)
				i = 0;
			else
				i++;
			continue;
		}
         //正常(人员未被淘汰参与报数且报数不为3)状况代码段
		tag++;           
		if (i == n - 1)
			i = 0;
		else
			i++;
	}
    //确定返回值
	i = 0;                
	while (circle[i] == -1)
		i++;

	free(circle);
	return i+1;
}

 (如有问题,欢迎指正)

  • 20
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青锋杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值