约瑟夫问题

著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到剩余一个人为止。一开始要站在什么地方才能避免被处决?
     解决思路:
     建立一个有40个元素的数组, 将元素的初值赋为1,第一个元素从1开始计数,凡是遇到计数值为3的倍数的元素,将其值赋为0,遍历结束后从数组首元素接着计数......直到数组中只有一个为值1 的元素为止,其下标加1,即为最后幸存者
#include <stdio.h>

#define N   41  //总人数
#define NUM 3   //出局的数字

void print (int *a, int n)
{
	int i;
	for (i = 0;i < n; i++)
	{
		printf ("%2d",a[i]);
	}
	putchar ('\n');
}

/*
  将所有人的值编为1,出局的的人编为0,直到只有一个1为止
*/
void Joseph (int *a)
{
	int temp = 0;   //报数
    int count = N;  //当前剩余1的数量
	
    while (1)
	{	
		int i;
		
		//遍历报数,超出总人数则第一个人接着报数
		for (i = 0;i < N; i++)  
		{
			if (a[i] == 0)   //遇到出局的人跳过报数
			{
				continue;   
			}
			temp++;
			if (temp % NUM == 0)   //判断是否出局,若出局值编为0
			{
				count--;
				a[i] = 0;
			}
		}
		if (count == 1)    //剩余一人结束报数
			break;
	}
}

int main ()
{
	printf ("Function : Joesphus.\n");

	int a[N] = {};

	int i;
	for (i = 0;i < N; i++)
	{	
		a[i] = 1;
	}

	print (a,sizeof(a)/sizeof(a[0]));

	Joseph (a);

	print (a,sizeof(a)/sizeof(a[0]));

	for (i = 0;i < N; i++)
	{
		if (a[i] == 1)
		{
			printf ("Winner is %d !\n", i+1);  //数组下标从0开始,所以第n个元素是第n+1个人的序号
		}
	}

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值