约瑟夫环问题


约瑟夫问题:

n个猴子按顺时针方向围成一个圈选大王,(编号从1---n),从第一个猴子开始报数,一直数到m,数到m的猴子就出列,剩下的猴子再接着从1开始报数,就这样一直到所有的猴子都出列,

分析:

我们可以模拟人工的办法,把n个数写在纸上排成一个圈,然后从 1 开始报数,没数到 m 的时候就把 m 划掉。循环做下去,直到所有的数都已经划掉为止。

我们按人工的方法写一个模拟的程序,就可以了。

用数组loop[]来存放 n 个数 相当与n个数排成的圈,用整形变量 ptr 来指向当前数到的数。划掉一个数的操作就是把它置为 0 ,并在数的时候跳过为 0 的数。

代码如下:


#include <stdio.h>
int main (){
	int n,m;
	int loop[305];
	while (~scanf ("%d%d",&n,&m)){
		for (int i=0;i<n;i++)
			loop[i] = i+1;
		int ptr = 0;
		for (int i=0;i<n;i++){
			int cout = 0;	//记录数了几个数
			while (cout < m){
				while (loop[ptr]==0)  //跳过所有划掉的数
					ptr = (ptr+1) % n;
				cout ++;  
				ptr = (ptr+1) % n;  //循环移动下一个位置
			}
			ptr -- ;  //回退一个位置。
			if (ptr < 0)
				ptr = n-1;
			if (i==n-1)
				printf ("%d\n",loop[ptr]);
			else 
				printf ("%d ",loop[ptr]);
			loop[ptr] = 0 ;
		}
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值