您的位置:首页 > 编程语言 > Java开发

.NET转JAVA之路005

2016-09-13 21:27 183 查看

约瑟夫环

约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后[1] 结果+1即为原问题的解。

这里我们简化模型,500个人小朋友围城一个圈,数三退出,求出最后一个人的下标是多少

思路一:构建一个500个bool数组,初始时全部为true,数到三时,赋值为false,

只要求出最后一个数组为true的下标数字,即为所求数字。

boolean[] arr=new boolean[500];//创建bool数组
for(int i=0;i<arr.length;i++){
arr[i]=true; //初始时都为true;
}

int leftcount=arr.length;//记录当前圈内还有多少人

int countNum=0;//1,2,3,1,2,3的记录值

int index=0; //当前的索引值,超出500返回0;

while(leftcount>1){//只要圈内人还多于1个人,继续执行
if(arr[index]==true){
countNum++;
if(countNum==3)
{
countNum=0;
arr[index]=false; //出列
leftcount--; //圈内人数减1
}
}

index++; //索引自增长
if(index==arr.length){
index=0; //超出索引值,返回到头部
}
}

for(int i=0;i<arr.length;i++)
{
if(arr[i]==true)
{
System.out.println(i); //获得唯一的一个没有出列的数字
}
}


思路二:小朋友手拉手(双向链表)

先上图:



//小朋友类
class Kid
{
int id;
Kid left;
Kid right;
}

class KidCircle
{
int count=0;
Kid first,last;
KidCircle(int n){
for(int i=0;i<n;i++){
add();
}
}

void add(){
Kid k=new Kid();
k.id=count;
if(count<=<
b93d
span class="hljs-number">0)
{
first=k;
last=k;
k.left=k;
k.right=k;
}else{
last.right=k;
k.left=last;
k.right=first;
first.left=k;
last=k;
}
count++;
}

void delete(Kid k)
{
if(count<=0)
{
return ;
}else if(count==1){
first=last=null;
}else{
k.left.right=k.right;
k.right.left=k.left;

if(k==first){
first=k.right;
} else if(k==last){
last=k.left;
}
}
count--;
}
}


主程序

public static void main(String[] args)
{
KidCircle kc=new KidCircle(500);
int countNum=0;
Kid k=kc.first;
while(kc.count>1)
{
countNum++;
if(countNum==3)
{
countNum=0;
kc.delete(k);
}
k=k.right;
}
System.out.println(kc.first.id);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: