看了好久的约瑟夫环
第一种是借用数组,最好理解
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);
}