无聊水河畔,看了看今年大华为上机题,比较高大上(shui),无监考,能讨论,还特么能百度谷歌。。。这才是写代码应该有的模式呀。。。最近正好在看J2EE,就随手写了个约瑟夫问题,顺便试试语法高亮插件>_<
/**
* 约瑟夫问题:设编号为1,2,。。。n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m的那个人出列,
* 他的下一位又从1开始报数,数到m的人又出列,以此类推,直到所有人出列为止,由此产生一个出队编号的序列。求最
* 后剩下人的编号。
*
* 很容易想到循环链表,我这里用的双向循环链表解法。
*/
package com.yosephu;
public class Yosephu
{
public static void main(String[] args)
{
//测试用例
Link link = new Link();
link.setLen(10);
link.setK(1);
link.setM(10);
link.init();
link.show();
link.play();
}
}
//节点类
class Node
{
int num;
Node pre;
Node next;
public Node(int num)
{
this.num = num;
}
}
//链表类
class Link
{
Node h = null;
Node temp = null;
//链表大小
int len = 0;
public void setLen(int len)
{
this.len = len;
}
int k = 0;
int m = 0;
public void setK(int k) {
this.k = k;
}
public void setM(int m) {
this.m = m;
}
//初始化链表
public void init()
{
for(int i=1;i<=len;i++)
{
Node node = new Node(i);
if(i == 1)
{
h = node;
temp = node;
}
else
{
if(i == len)
{
node.pre = temp;
temp.next = node;
node.next = h;
h.pre = node;
}
else
{
node.pre = temp;
temp.next = node;
temp = node;
}
}
}
}
public void play()
{
Node temp = this.h;
//1。先找到开始数数的第k个人
for(int i=1;i<k;i++)
{
temp = temp.next;
}
while(this.len !=1)
{
//2。数m下
for(int j=1;j<m;j++)
{
temp = temp.next;
}
//打出出列人的编号
System.out.println("出列人的编号:"+temp.num);
//3。将数到m的人,踢出链表
temp.pre.next = temp.next;
temp.next.pre = temp.pre;
temp = temp.next;
this.len--;
}
System.out.println("最后一个是:"+temp.num);
}
public void show()
{
Node t = this.h;
do
{
System.out.println(t.num);
t = t.next;
}
while(t != this.h);
}
}