约瑟夫环

看了好久的约瑟夫环

第一种是借用数组,最好理解

int main(){
	int n,m=0,k=0,i;
	scanf("%d",&n);
	int a[n+1];
	for(i=0;i<=n;i++) a[i]=i;
	while(m<n-1){
		for(i=1;i<=n;i++){
			if(a[i]!=0&&k!=3){
				k++;
			}
			if(k==3){
				a[i]=0;
				m++;
				k=0;
				printf("%d  ",i);
			}
		}
	} 
	for(i=1;i<=n;i++){
		if(a[i]!=0){
			printf("最后剩下的是%d\n",i);
		}
	}

 第二种是递归,循环队列,要注意是从1开始数

int ysfdg(int sum,int value,int n){//递归解法 
	if(n==1)
		return (sum+value-1)%sum;
	else
		return(ysfdg(sum-1,value,n-1)+value)%sum;
}
int main(){
	int n,k,i;
	scanf("%d %d",&n,&k);
	for(int i=1;i<=n;i++){
		printf("%d ",ysfdg(n,k,i));
	}
	return 0;

第三种是数学解法,反复迭代,也是从0开始数 f(N,M) =(f(N-1,M)+M)%N,f(1)=0,f(i)=(f(i-1)+m)%i;i为第i次退出圈子的人,注意圈子内人编号从0开始,故s+1

int main(){//数学解法 
	int n,m,s=0,i;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++)
		s=(s+m)%i;
	printf("%d",s+1);
	return 0;

Eeny Meeny Moo,就是n-1个城市参与

#include<stdio.h>
int ysf(int n,int m){
	int s=0,i;
	for(i=1;i<=n-1;i++)//第一个城市删去,n-1 
		s=(s+m)%i;//i表示规模有几人 
	return s;//返回的值是按照0开始的 
}
int main(){//0开始 报数为m-1的人出列  1开始,m出列 
	int i,j;
	for(i=3;i<=12;i++)
		for(j=2;;j++)//由于第一个城市对应0,第二个城市对应1,再加上第一个城市被删,所以第二个城市对应0 
			if(ysf(i,j)==0){
				printf("%d %d\n",i,j);
				break;
			}
	return 0;
}

另一种,注意,本意有n个人参与,但因为指定从第一个人退出圈,便舍去第一个人(0号),将所有人编码往前推1,原来的1-->0,2-->1……故现有n-1个人参与,当得到最终结果时,s+2

#include<stdio.h>
int main(){
	int n,m=3,s=0;
	scanf("%d",&n);
	for(int i=2;i<=n-1;i++) 
		s=(s+m)%i;
	printf("%d",s+2); 
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值