package four;
/*
2. 约瑟夫环问题(两道题)
2.1:
我们班上50个人组成一个大圈,先是1-7报数,数字是5号的同学出来,重复凑够10个人
然后剩下40个人1-11报数,数字是9号的同学出来, 重复凑够10个人,
选出的20个人组成一个小圈,1-13报数,把11挑出来,重复凑够 5 个人,这五个人就是被选出出去找食物的人,他们回来不了了, 没被选中的 15 人重新回到大圈里.
这样重复七天,看还有谁活着
2.2
我们班上50个人组成一个大圈,先是1-7报数,数字是5号的同学出来,重复凑够10个人
然后剩下40个人1-11报数,数字是9号的同学出来, 重复凑够10个人,
选出的20个人组成一个小圈,1-13报数,把11挑出来,这样重复凑够((班上还活着的人数/10)(四舍五入))的人,然后再产生和人数相等的N个0-1的随机数分配给每个人,随机数大于等于0.5的幸存回到集体,否则死去, 没被选中的人重新回到大圈里,
然后再进到第二天的选人,一直重复七天,看班上还有谁是活着的?

*/
public class Josephus
{
public static void main(String[] args)
{
//班上的50个人组成一个数组
Josephus josephus=new Josephus();
int a[]=josephus.make();
System.out.println("班上本来的人");
josephus.show(a);
System.out.println("方法一中一周中每天出去的人");
josephus.week1(a);
int b[]=josephus.make();
System.out.println("方法二中每一周出去和死的人");
josephus.week2(b);
}
public void week2(int[] a)
{
for(int x=0;x<7;x++)
{
int[] maybedeathperson=end(strat20(a),(int)((this.curperson(a))*1.0/10+0.5));
System.out.print("出去的:");
for(int y=0;y<maybedeathperson.length;y++)
{
System.out.printf("%-5d",maybedeathperson[y]);
}
System.out.print("死了的:");
for(int y=0;y<maybedeathperson.length;y++)
{
double live=Math.random();
if(live<0.5)
{
a[maybedeathperson[y]-1]=0;
System.out.printf("%-5d",maybedeathperson[y]);
}
}
System.out.println();
}
System.out.println("最后活着的人");
for(int x=0;x<a.length;x++)
{
if(a[x]!=0)
{
System.out.printf("%-4d",a[x]);
}
}
System.out.println();


}
public int curperson(int[] a)
{
int curperson=0;
for(int x=0;x<a.length;x++)
{
if(a[x]!=0)
{
curperson++;
}
}
return curperson;
}
public void week1(int[] a)
{
for(int x=0;x<7;x++)
{
//选出的五个人
int[] deathperson=end(strat20(a),5);
for(int y=0;y<deathperson.length;y++)
{
a[deathperson[y]-1]=0;
System.out.printf("%-5d",deathperson[y]);
}
System.out.println();
}
System.out.println("最后活着的人");
for(int x=0;x<a.length;x++)
{
if(a[x]!=0)
{
System.out.printf("%-4d",a[x]);
}
}
System.out.println();

}
public int[] end(int[] Array,int number)
{
//选出的5个人
int a[]=this.CopyArray(Array);
int b[]=new int[number];
int count=0,falg=0;
big:
while(true)
{

for(int x=0;x<13;x++,falg++)
{
//如果标志的位置是0,说明这个人已经出去了
while(a[falg%a.length]==0)
falg++;
if(x==11-1)
{
b[count++]=a[falg%a.length];
a[falg%a.length]=0;
if(count==number)
break big;
}
}
}
return b;
}
//游戏开始选出的20个人
public int[] strat20(int[] Array)
{
//先找出选出的20个人
int a[]=this.CopyArray(Array);
int b[]=new int[20];
int count=0,falg=0;
//先挑出十个人
big1:
while(true)
{
for(int x=0;x<7;x++,falg++)
{
//如果标志的位置是0,说明这个人已经出去了
while(a[falg%a.length]==0)
falg++;
if(x==5-1)
{
b[count++]=a[falg%a.length];
a[falg%a.length]=0;
if(count==10)
break big1;
}

}
}
//再挑出10个人
falg=0;
big2:
while(true)
{

for(int x=0;x<11;x++,falg++)
{
//如果标志的位置是0,说明这个人已经出去了
while(a[falg%a.length]==0)
falg++;
if(x==9-1)
{
b[count++]=a[falg%a.length];
a[falg%a.length]=0;
if(count==20)
break big2;
}
}
}
return b;
}
public int[] CopyArray(int[] a)
{
int[] b=new int[a.length];
for(int x=0;x<a.length;x++)
{
b[x]=a[x];
}
return b;
}
public int[] make()
{
int a[]=new int[50];
for(int x=0;x<50;x++)
{
a[x]=x+1;
}
return a;
}
public void show(int[] a)
{
for(int x=0;x<a.length;x++)
{
System.out.printf("%-4d",a[x]);
}
System.out.println();
}
}