11.20笔记之约瑟夫环之C语言

 

传说约瑟夫当年活下来就是靠快速计算这个问题。

n 个人围成一圈,编号依次为1,2,3...n。 从第一个人开始报数,数到 m 的人出列,再由下一个人重新从 11 开始报数,数到 m 的人再出圈。 以此类推,直到所有的人都出列。 请输出依次出圈人的编号。

输入格式

两个整数 n,m   1 =n,m <= 100。

输出格式

n 个用空格分隔的整数,表示出圈人的编号。

示例输入

6 4

样品输出

4 2 1 3 6 5

解题思路 

1.定义数组a[1,2,.....n]编号对应数组数字

2.定义i,j

i表示报的数(用于淘汰人)(淘汰的人数组中的数变为0)

j表示报数字的次数(用于对应位置)

3.增加i开始报数

当i对应的数组中的数为0时i--(跳过次人)

用(j-1)%n+1表示当前人的位置当

(j-1)%n+1(当J为n的倍数时不会=0而是=n)

4.i最大值为n*m

当i=n*m时停止输出(j-1)%n

#include<stdio.h>
int main(){
	int n,m;
	scanf("%d %d",&n,&m);
	int i=1;
	int a[100];
	while(i<=n){
		a[i]=i;
		i++;
	}//所有数组的数存自己编号
	int j=1;
	i=1;
	while(1){
		if(a[(j-1)%n+1]==0){
			i--;
		}
		if(i%m==0 && a[(j-1)%n+1]!=0){//当i为m的倍数且此时此位置的数不是已经淘汰的数
			if(j%n==0){//如果时最后一个数则a[n]=0
				a[n]=0;
				printf("%d ",n);
			}else {//如果不是最后一个数则此数变为0(淘汰)
			a[(j-1)%n+1]=0;
			printf("%d ",(j-1)%n+1);
		}
		}
		i++;
		j++;
		if(i==n*m){//i为最大值输出最后一个
			printf("%d",(j-1)%n);
			break;
		}
	}
	i=0;
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值