约瑟夫问题

题目编号 :Exp04-Enhance02,GJBook3-06-26

题目名称:约瑟夫问题(Josephus)

题目描述:

古代某法官要判决 n 个犯人死刑, 他有一条荒唐的逻辑, 将犯人首尾相接排成圆圈,所有计数从1开始; 然后从第 s 个人开始数, 每数到第 m 个犯人,则拉出来处决; 然后再数 m 个,数到的犯人再处决;... ; 但剩下的最后一个犯人可以赦免。编程序,给出处决顺序,并告知哪一个人活下来。

输入:三个正整数 n(≤1000),s和m,都可以使用int类型变量表示。

输出:依次输出被处决人员的编号,每个编号之间用一个西文空格间隔,最后一个编号后无字符。
 

样例:

输入:6 1 5
输出:5 4 6 2 3 1
#include <stdio.h>
int main() {
	int n, s, m, a[1000];          //n个犯人,从s开始数,每次数到m的杀掉
	scanf_s("%d %d %d", &n, &s,&m);
	int i,j;
	int x=s-1,cnt = 0;
	for (i = 0; i <= n - 1; i++) {
		a[i] = i;
	}
	while (cnt <= n - 2) {         //若无格式要求,此处可写成cnt<=n-1,直接输出所有编号
		x = (x - 1+m) % (n-cnt);
		printf("%d ", a[x] + 1);   //由于是从a[0]开始存放0,所以每次选中的号码为下标+1。
		a[x] = -1;
		j = 0;                     //每处置一个人后,需要将剩余人重新放入数组,从0开始放,每次将j置0
		for(i=0;i<=n-1-cnt;i++)
			if (a[i] != -1) {
				a[j] = a[i];
				j++;
			}
		cnt++;
	}
	j--;
	printf("%d", a[j] + 1);
	return 0;
}

以上代码是采用的从a[0]开始存放0,即元素等于下标,相当于把每个犯人的编号-1后存放,故输出时要+1.

如果从a[0]开始存放编号1,则直接输出。

如果从a[1]开始存放1,(a[0]在题中无意义),则需注意:1.取余的特殊情况,由于a[0]不存在,下标x取到零时需将x赋值n-cnt。2.输出最后一个编号时,数组中仅剩一个元素a[1],任何正整数%1=0,a[0]无意义,因此最后一个号码需单独输出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值