约瑟夫问题

[题目大意]: 约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。

[输入]: 每行是用空格分开的两个整数,第一个是 n, 第二个是 m ( 0 < m,n <=300)。最后一行是: 0 0

[输出]: 对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号 样例输入

6 2

12 4

8 3

0 0

样例输出

5

1

7 解题步骤:

1、首先是定义节点,每个猴子有一个编号和下一个猴子的信息

复制代码
 1 class Node<T> {
 2 
 3     T data;
 4     Node next;
 5 
 6     public Node(T data, Node<T> next) {
 7         this.data = data;
 8         this.next = next;
 9     }
10 
11     public Node getNext() {
12         return next;
13     }
14 
15     public void setNext(Node next) {
16         this.next = next;
17     }
18 
19     public T getData() {
20         return data;
21     }
22 
23     public void setData(T data) {
24         this.data = data;
25     }
26  } 
复制代码

2、建立循环链表

  

        public void add(T data) {

 

if (size == 0) {
head = new Node<T>(data, null);
tail = head;
current = head;
} else {
tail.next = new Node<T>(data, head);
tail = tail.next;
}
size++;
}

 3、猴子数到n时,就退出循环链表中

public T remove(boolean flag) {

 

if (flag) {
if (current.next == head) {
head = current.next.next;
} else if (current.next == tail) {
tail = current;
}
current.next = current.next.next;
size--;
return current.getData();
} else {
current = current.next;
return current.getData();
}
}

 

 最后就是在主函数中测试:

public static void main(String[] args) {
Scanner s = new Scanner(System.in);
while (true) {
int k = 1;// 用于计数,
int m = s.nextInt();// 表示数到m时m退出
int n = s.nextInt();// 表示公有多少人
if (m == 0 && n == 0)
break;
Josephus<Integer> l = new Josephus<Integer>();
for (int i = 0; i < n; i++) {
l.add(i);
}
while (true) {
if (k % m != 0) {
l.remove(false);
k++;
} else {
l.remove(true);
k = 1;// 如果人数是k的整数倍,则k的值为1
}
if (l.getSize() == 1) {
System.out.println(l.current.getData());
break;
}
}
}

 

 下面是全部的代码:

View Code 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @   开心学习吧  阅读(323)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示