約瑟夫環

看了好久的約瑟夫環

第一種是借用數組,最好理解

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)%M

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章