约瑟夫环(1+2)
n 个小孩围坐成一圈,并按顺时针编号为1,2,…,n,从编号为 p 的小孩顺时针依次报数,由1报到m ,当报到 m 时,该小孩从圈中出去,然后下一个再从1报数,当报到 m 时再出去。如此反复,直至所有的小孩都从圈中出去。请按出去的先后顺序输出小孩的编号。
每行是用空格分开的三个整数,第一个是n,第二个是p,第三个是m (0 < m,n < 300)。最后一行是:0 0 0
#include<stdio.h>
void ysf(int n,int p,int m){
int children[301];
for(int i=1;i<=n;i++)
children[i]=i;
int index=p;//从编号为p的小孩开始
int remaining=n;
while(remaining>0){
//数到m
for(int count=1;count<m;count++){
index=(index%n)+1;
while(children[index]==0)//跳过已经出圈的小孩
index=(index%n)+1;
}
printf("%d ",children[index]);
children[index]=0;
remaining--;
//移动到下一个有效的小孩
if(remaining>0){
index=(index%n)+1;
while(children[index]==0)
index=(index%n)+1;
}
}
printf("\n");
}
int main(){
int n,p,m;
while(1){
scanf("%d %d %d",&n,&p,&m);
if((n==0)&&(p==0)&&(m==0))
break;
ysf(n,p,m);
}
return 0;
}
编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数,报到 m 的人离开。
下一个人继续从 1 开始报数。
n-1 轮结束以后,只剩下一个人,问最后留下的这个人编号是多少?
约瑟夫环
#include<stdio.h>
int ysf(int n,int m){
int p=0;
for(int i=2;i<=n;i++)
p=(p+m)%i;
return p+1;
}
int main(){
int n,m;
scanf("%d,%d",&n,&m);
printf("%d",ysf(n,m));
return 0;
}