约瑟夫环的函数问题

约瑟夫问题:N个人围成一圈,从第一个人开始报数,数到M的人出圈;再由下一个人从1开始报数,数到M的人出圈;……直到只剩1人,输出依次出圈的人的编号。

N,M由键盘输入,0 <M <= N <20

函数第一个参数设计为指针,传主函数的数组作为参数。输出时,每个数字后有且仅有一个空格。

yuesufu.jpg

例如N=7,M=2,表示7个人围坐一圈,从1号开始报数,数到2的就出列。第一轮转圈中,2、4、6号依次出列。还剩下7、1、3、5四个数字。第二圈又是数到2的数列,1和5出列。第三圈的时候,只剩下3和7列。最终的输出结果是: 2 4 6 1 5 3 7

函数接口定义:

void yuesefu(int *p,int n,int m);

指针 p 指向一个一维数组,数组的元素数量是n 个。 m 表示传入的报数的数字。

裁判测试程序样例:


#include<stdio.h>
#define L 20
//指针p指向的一维数组有n个元素,然后按照数字m进行报数出列。 
void yuesefu(int *p,int n,int m);
int  main()
{
    int a[L];
    int M,N;
    scanf("%d%d",&N,&M);
    yuesefu(a,N,M);
}

/* 请在这里填写答案 */

输入样例:

有7个人,从第一个人开始报数,数到2的出列。

7 2

结尾无空行

输出样例:

出列的顺序,注意每个数字后,有且仅有一个空格。

2 4 6 1 5 3 7 

首先我们来分析这道题,n个人围成一圈,轮流报数,每次报到m的人出列,这样到最后,所有人都会出列。对于这道题呢,需要我们用再定义一个数组进行记录出列情况,,先对他初始化为0,再进入循环

void yuesefu(int *p,int n,int m)
{
	int k = 0,u = 0;//利用u来记录出列的数的个数,判断是否结束循环,k来记录报数情况
	int i;
	int b[25] = {0};//b[]记录是否已经出列
	for(i = 0;i < n;i++)
	{
		p[i] = i + 1;//对数组进行初始化,填数
	}
	while(u < n)//判断结束条件
	{
		for(i = 0;i < n;i++)
		{
			
			if(b[i] == 0)//只有未出列的数才可以出列
			{
				k++;
				if(k == m)//当报数为m时出列
				{
				
				printf("%d ",p[i]);//打印
				b[i] ++ ;//标记已经出列的数
                k = 0 ;//重新进行报数
                u++;//记录出列的数的个数,用于结束循环
				}
			}
		}
	}
	
}

如果出列那我们 让他加1,每次我们判断只有报到m并且记录数组为0的数打印出来,当打印n个时,结束循环即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

安特尼

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

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

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

打赏作者

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

抵扣说明:

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

余额充值