思路
1.把人的序号写入数组里
2.然后通过key找到要被杀的人在数组里的下标
3.打印那个人序号
4.然后如果那个数不是有效数组的最后一个,要将这个数后面的数前移,即整个数组前面部分都是没有被处理过的,而后面的都是无意义的数,前面的是有效的
5.这样我们假装数组在不断变短,用n来标记最后一个(n-1)
带注释版
public class yuesefu
{
public static void main(String[] args)
{
int N=5,S=1,D=2; //N总数、S第一次在哪儿开始数、D数几次
int n=N; //n是剩下的人数
int []a=new int [N]; //用数组存储人的序号
for(int i=0;i
{
a[i]=i+1;
}
int key=(S+D-2)%n;//key是第一次简化后应该被显示出来的数组下标,S+D-1是个数,再减1就是那个数的下标
for(int i=1;i<=N-1;i++) //循环N-1次取出N-1个那么只剩1个了,即剩下被赦免那个
{
System.out.print(a[key]+"\t"); //把要取出的人显示出来
if(key
{
for(int j=key;j<=n-2;j++)//这里用覆盖的方法,比如取出的数是a[2],那么将a[3]、a[4]……向前覆盖
{ //假如覆盖3次以后,那么数组最后面的3个数是没有实际意义的,就不必向前覆盖,即前移到n-2
a[j]=a[j+1]; //j<=n-2是因为 a[j]=a[j+1];即最后会是a[n-2]=a[n-1];最后一个位置没有意义
}
}
n--;//将人数减少,数组是不变的,但是数组后面无意义的数就不算了,即假装数组在变短,数组只有前面有意义
key=(key+D-1)%n; //这里更新下一个应该被取出的数在数组里的下标
}
System.out.print(a[0]); //输出最后一个数,即被赦免的数,而且a[1]、a[2]……在我们看来没意义了
}
}
不带注释
public class yuesefu
{
public static void main(String[] args)
{
int N=5,S=3,D=4;
int n=N;
int []a=new int [N];
for(int i=0;i
{
a[i]=i+1;
}
int key=(S+D-2)%n;
for(int i=1;i<=N-1;i++)
{
System.out.print(a[key]+"\t");
if(key
{
for(int j=key;j<=n-2;j++)
{
a[j]=a[j+1];
}
}
n--;
key=(key+D-1)%n;
}
System.out.print(a[0]);
}
}