助教c/c++:n个人围成一圈报数问题

以下三个问题都属于同类型的问题,其中两道题目是助教时的实验题,还有一道是华为在成都招聘时的机试题目。

在这三个问题中,问题1考虑的最简单,用指针实现;问题2考虑最全面,用结构体实现;问题3用到了函数。

问题1:有n个人围成一圈,顺序排号。从第一个人开始报数,凡报到3的人退出圈子,问最后留下的是几号?

源程序:

#include<stdio.h>
#define max 15
int main()
{
	int i,k,n,m,num[max],*p;
	printf("输入开始报数时总人数:");
	scanf("%d",&n);//开始报数前的人数。
	p=num;//指针指向数组第一位num[0]
	for(i=0;i<n;i++)//把n个人进行编号为1—n。
		*(p+i)=i+1;
	printf("依次出圈的人的编号:");
	i=0;k=0;m=0;
	while(m<n-1)//m为圈外人数。当m=n-1时,不再执行while循环,此时圈内还有一个人。
	{
		if(*(p+i)!=0)//报数。
			k++;
		if(k==3)
		{
			printf("%d ",*(p+i));//按顺序依次输出出圈的人的编号。
			*(p+i)=0;//对于出圈人数,其值置为0。
			m++;//圈外人数加1。
			k=0;//重新开始报数。
		}
		i++;//指针指向下一位。
		if(i==n)//指针移到最后一位时,重新赋值
			i=0;//printf("\n");
	}
	for(i=0;i<n;i++)//输出最后一位出圈的人的编号
		if(*(p+i)!=0)
			printf("\n最后一位出圈的人的编号:%d\n",*(p+i));
	return 0;
}

运行结果:


问题2:n个人围成一圈,从第s个人开始按顺时针1,2,3,4,……,m的顺序报数,数到m的人出圈,然后从出圈的下一个人开始重复此过程,输出所有出圈人的顺序。

要求:结构体指针。

源程序:

#include<stdio.h>
#define N 10
struct child
{
	int no;
	int next;
};
struct child link[N];
void main()
{
	int i,n,m,s,count,h;//定义变量
	printf("输入围圈人数,出圈报数,开始报数位置:");
	scanf("%d,%d,%d",&n,&m,&s);//n是总人数,m是出圈号,s是初始报数位置。
	for(i=1;i<=n;i++)
	{
		if(i==n)link[i].next=1;//围成一圈,
		else link[i].next=i+1;
		link[i].no=i;
	}
	count=0;
	if(s==1)h=n;
	else h=s-1;
	//如果从1号开始报数,1号的前一位是n号。如果从s开始报数,s的前一位是s-1号。
	printf("出圈顺序为:");
	while(count<n-1)//count是圈外人数,当count=n-1时,不再执行while循环,圈内还剩下一人。
	{
		i=0;
		while(i!=m)
		{
			h=link[h].next;
			if(link[h].no)//判断当前号的值是否已置0,
				i++;
		}
		printf("%d ",link[h].no);//依次输出出圈的人的编号
		link[h].no=0;
		count++;
	}
	printf("\n最后出圈的人的编号:");
	for(i=1;i<=n;i++)//最后出圈的人的编号
		if(link[i].no!=0)
		printf("%d",link[i].no);
}

运行结果:


问题3:#华为机试#

计算最后一个出列者的编号 
描述: 现在有n个竞争者围坐一圈,争夺一个很有吸引力的工作(年薪100w $)。假设这些人编号1,2,。。。,n。第一次从1开始报数,数到m(m>0)的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列。以此类推,直到所有人出列为止。老板说最后一个出列的人将获得这份工作。
如果你也想竞争这份工作,那么你会坐着哪个位置上?
实现一个函数,当老板告诉你n和m时,返回得到工作的那个人的编号。
运行时间限制: 无限制 
内存限制: 无限制 
输入: 竞争者人数,报数
输出: 最后出列的竞争者的编号。异常则返回 -1。
样例输入: 10,10 
样例输出: 8 
源程序:

#include<stdio.h>
void main()
{
	int search(int n,int m);
	int n,m,lucky;//定义变量
	printf("竞争者人数,出圈报数:");
	scanf("%d,%d",&n,&m);//n是总人数,m是出圈号,s是初始报数位置。
	lucky=search(n,m);
	if(lucky==-1)
		printf("异常!!!");
	else
		printf("幸运者编号:%d\n",lucky);
}
int search(int n,int m)
{
	int num[20];int *p=num;
	int i,j,k,count,h,lucky=-1;
	for(i=0;i<n;i++)
	{
		*(p+i)=i+1;
	}
	count=0;j=0;
	h=n;i=0;k=0;//从第1号开始报数,1号的前一位是n号。
	while(count<n-1)//count是圈外人数,当count=n-1时,不再执行while循环,圈内还剩下1人。
	{
		if(*(p+i)!=0)k++;
		if(k==m)
		{
			*(p+i)=0;
			k=0;
			count++;
		}
		i++;
		if(i==n)
			i=0;
	}
	for(i=0;i<n;i++)//最后出圈的人的编号
		if(*(p+i)!=0)
			lucky=*(p+i);
	return lucky;
}

运行结果:




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值