问个经典的算法。。大家来动动脑筋

a2bb 2008-02-26 02:19:05
n个人围成一圈,从第一个人开始依次从1到m循环报数,当报到m的时候此人出圈,然后从下一个人开始重新报数,直到圈中只剩一人为止.打印出最后一个人的原始编号和出圈序列
...全文
833 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
hjxaut 2008-03-02
  • 打赏
  • 举报
回复
这个叫约瑟夫环问题,找一下相关问题就知道了
lujiaxing2007 2008-02-28
  • 打赏
  • 举报
回复
呵呵

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ysfh
{
class Program
{
public const int m = 23;


static void Main(string[] args)
{
int r = m,a=1,s=1;
List<int> poped=new List<int>();

List<int> n = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
while (n.Count > 1)
{
for (int j = s; j <= n.Count;j++ )
{
if (a != r)
{
s = 1;
a++;
}
else
{
poped.Add(n[j-1]);
n.Remove(n[j-1]);
s = j;
a = 1;
break;
}
}
}

Console.WriteLine("出圈序列");
foreach (int ss in poped)
{
Console.WriteLine(ss);
}
Console.WriteLine("最後一個人");
foreach (int w in n)
{
Console.WriteLine(w);
}
Console.ReadLine();
}
}
}
imetzhuozhuo 2008-02-28
  • 打赏
  • 举报
回复
循环双向链表解决如下:
class TPerson {
String no;

TPerson pre;

TPerson next;

public TPerson(String no, TPerson pre, TPerson next) {
this.no = no;
this.pre = pre;
this.next = next;
}

public TPerson(String no) {
this(no, null, null);
}

}
class TPersonList {
TPerson first;

TPerson last;

public synchronized void insertAtFront(String no) {
if (isEmpty()) {
first = last = new TPerson(no);
}
else {
TPerson addItem = new TPerson(no, last, first);
first.pre = addItem;
last.next = addItem;
first = addItem;
}
}

public synchronized void insertAtBack(String no) {
if (isEmpty()) {
first = last = new TPerson(no);
}
else {
TPerson addItem = new TPerson(no, last, first);
first.pre = addItem;
last.next = addItem;
last = addItem;
}
}

public synchronized String removeAtFront() throws RemoveException {
if (isEmpty()) {
throw new RemoveException("the list is empty!");
}

String no = first.no;
if (first == last) {
first = last = null;
}
else {
last.next = first.next;
first = first.next;
}

return no;
}

public synchronized String removeAtBack() throws RemoveException {
if (isEmpty()) {
throw new RemoveException("the list is empty!");
}

String no = last.no;
if (first == last) {
first = last = null;
}
else {
first.pre = last.pre;
last = last.pre;
}

return no;
}

public boolean isEmpty() {
return first == null;
}

public String toString() {
if (isEmpty()) {
return "a empty list!";
}

String result = first.no;
TPerson curr = first.next;
if (curr != null) {
while (curr != first) {
result += ", " + curr.no;
curr = curr.next;
}
}

return result;
}
}

public class LoopCounter {

public void count(int n, int m) {
TPersonList list = new TPersonList();
for (int i = 1; i <= n; i++ ) {
list.insertAtBack("" + i);
}

if (m < 1) {
throw new RuntimeException("invalid argument!");
}
else if (m == 1) {
System.out.println(list);
}
else {
TPerson curr = list.first;
int count = 1;
String no = null;
int quitNo = 0;
while (list.first != list.last) {
if (count == m) {
count = 1;
quitNo++ ;
no = curr.no;
System.out.println("no: " + no);
System.out.println("quitNo: " + quitNo);
list.first = curr.next;
list.first.pre = curr.pre;
list.last = curr.pre;
list.last.next = list.first;
curr = list.first;
}
curr = curr.next;
count++ ;
}

quitNo++ ;
System.out.println("the last person no: " + list.first.no + ", quitNo: " + quitNo);
}
}

public static void main(String[] args) throws RemoveException {
LoopCounter counter = new LoopCounter();
counter.count(3, 5);
}
}
ninesea 2008-02-28
  • 打赏
  • 举报
回复
14楼的结果少加了1 呵呵
JettHuang 2008-02-27
  • 打赏
  • 举报
回复
约瑟夫环啊!!!!
ludahumsn 2008-02-27
  • 打赏
  • 举报
回复

//算法思想:m为人数,n为步长,所有人出列要进行m轮,每轮过后已经出列的人,不在新的一轮的判断之内(过滤掉)

public class CycleMan {

public static void main(String[] args) {
play(10000, 137);
}
//用于过滤
private static boolean same(int[] p,int m,int n){
for(int i=0;i<m;i++){
if(p[i]==n){
return true;
}
}
return false;
}
//算法执行体
public static void play(int playerNum, int step){
int[] p=new int[playerNum];
int counter = 1;//走过步数:counter
while(true){

if(counter > playerNum*step){//退出while,根据走过的步数
break;
}
for(int i=1;i<=playerNum;i++){
//过滤
while(true){
if(same(p,playerNum,i)==false)
break;
else
i=i+1;
}
if(i > playerNum)break;//退出for
//根据走过的步数和步长判断此人是否应该出列,若是则输出此人,并将其存入出列队列中,若不是继续走下去
if(counter%step==0){//counter代表已经走过的步数
System.out.print(i+" ");
p[counter/step-1]=i;
}
counter+=1;
}
}
System.out.println();
}
}
zghua851004 2008-02-27
  • 打赏
  • 举报
回复
学习

lxjlan 2008-02-27
  • 打赏
  • 举报
回复
奇怪,为啥问这个呀。。。。这个算法很经典呀。。。
在很多c++的书上都是有的。。。也是很多课后练习的题目。。。
ninesea 2008-02-27
  • 打赏
  • 举报
回复
14楼的结果不对
zhangyue02135 2008-02-27
  • 打赏
  • 举报
回复

#include <stdio.h>

#define N 10
#define M 5

int
main(void)
{
int people[N] = {0};

int i = 0;

//give the number for people from 1 to N
for (; i<N; i++)
{
people[i] = i+1;
}

int tmp = 1;
i = 0;
int num = 0;

while (num < N)
{
if (tmp == M)
{
printf("%d\n", people[i]);
tmp = 0;
people[i] = 0;
num ++;
}
i++;
if (i == N) i = 0;
if (people[i] != 0)tmp ++;
}

return 0;
}
输入n=10, m=5. 输出为:
5
10
6
2
9
8
1
4
7
3
shiqicai 2008-02-27
  • 打赏
  • 举报
回复
顶14楼,约瑟夫环问题。
求模答案就出来了,还用得着模拟?
ybyb14 2008-02-27
  • 打赏
  • 举报
回复
学习,紫竹的方法不错
iammajia001 2008-02-27
  • 打赏
  • 举报
回复
19楼说的对,有数学解法的
循环就可以了,具体BAIDU
超级大笨狼 2008-02-27
  • 打赏
  • 举报
回复
做一个首尾相连的链表。
qin4689 2008-02-27
  • 打赏
  • 举报
回复
up
wuxo84 2008-02-26
  • 打赏
  • 举报
回复
学习
healer_kx 2008-02-26
  • 打赏
  • 举报
回复
这个题目用一个数组就足够了。
被轮到的就置数为其相反数。要善用数据本身结构。

这样做的效果是最快的,特别是注意代码中使用的技巧。

public static void main(String[] args) {

int a[] = { 1, 2, 3, 4, 5, 6 };
int i = 0;
int c = 0;
int M = 2;
int count = 0;
boolean has = true;
while (has) {

i++;
i %= a.length;
int ad = i - 1 < 0 ? a.length - 1 : i - 1;
if (a[ad] < 0) {
continue;
}
c++;
c %= M;
if (c == 0) {
has = ++count < a.length;
a[ad] = -a[ad];
System.out.println(-a[ad]);
}

}

}



sunnylyy 2008-02-26
  • 打赏
  • 举报
回复
嗬嗬,约瑟夫环问题。

贴个能算最后一个人编号的程序,很短。

public class Test{
public static void josephus(int N,int M){
int s=0;
for(int i=2;i<=N;i++){
int k=M%i;
s=(s+k)%i;
}
System.out.println(s);
}
public static void main(String[] args){
josephus(5,2);
}
}

打印出圈序列的话,应该会变复杂一点,不过也可以在O(N)的时间内实现。


fancyboy2050 2008-02-26
  • 打赏
  • 举报
回复
能解释下不?写点注释。。。。

我写的 挺傻

import java.util.ArrayList;
import java.util.*;

public class Test1{
public static void to(int total, int number) {
List<Integer> list = new ArrayList<Integer>(total);
for(int i=1;i<=total;i++) {
list.add(i);
}
int j = 1;
int l = 1;
while(total > 0)
{
int k = list.size();
if(k==1)
{
System.out.println(list.get(0));
break;
}else{
if(l <=k )
{
if(j == number)
{
Integer in = (Integer)list.get(l-1);
System.out.println(in);
list.remove(in);
j = 1;
total--;
}else{
l++;
j++;
}
}else{
l = 1;
if(j == number)
{
Integer in = (Integer)list.get(l-1);
System.out.println(in);
list.remove(in);
j = 1;
total--;
}else{
l++;
j++;
}
}
}
}
}

/**
* @param args
*/
public static void main(String[] args) {
Test1.to(10, 5);
}
}
  • 打赏
  • 举报
回复
这个一般不是用循环链表来做的吗?
加载更多回复(11)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧