C语言数组实现约瑟夫问题

问题描述

从n个人中抽取一个中奖者,抽取方法如下:所有人围成一圈,第一个人从1开始报数,选定一个数m;报到数m的人出列,下一个人继续从1开始报数,直到剩余最后一人即为中奖者

要求:用C语言数组结构实现

思路:
1.因为是采用数组结构,故实现循环报数可采用数组下标取模方法
2.因为数组删除元素操作比较复杂,故可采取标记位方法标记出列人数:即数组所有元素初始化为0,报到m时将该数组元素标记为1表示此位置人已出列,同时输出出列人数下标;遍历数组时检查该元素是否为出列状态,是则跳过(即已出列人数不参与报数)
3.设置一个计数变量count和遍历变量i,当count达到m时,对i进行取模得到的即为对应要出列的元素下标,将其置为1,同时count变量置为0(为何置0见代码注释)
注意点:
1.应注意报数从1开始,而数组下标是从0开始,故实际出列人序号应该是下标加1
2.最后一个出列人即为中奖者

实现代码

#include <stdio.h>
#include <stdlib.h>

int josephus(int a[], int, int);

int main() 
{
	int b, m;
	printf("请依次输入数组长度和淘汰序号:");
	scanf("%d %d",&b,&m);
	int a[b];
	int i=0;
	for(;i<b;i++)
	    a[i]=0;
	josephus(a, b, m);
}
int josephus(int a[], int b, int m)
{
	int k=0,i=0,count=1,l=b;
	for(;l>=1;) 
	{
		if (count==m)
		{
			k=(i)%b;
			a[k]=1;
			printf("k=%d\n",k+1);//依次输出出列人的序号,最后一个即为中将者
			l--;
			count=0;//因为此时遍历下标还在出列元素,而下一个元素才是从1开始报数,故此处应将count置为0,带下标i遍历至下一个未出列元素时count再加1
		}
		i++;
		if (a[i%b]!=1)
			count++;
	}
}

时间复杂度分析

因为只用了一个for循环进行遍历,表示一共需要出列的人数,故时间复杂度与参与抽奖的人数成线性关系,为O(n)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值