“数三退一”游戏解法

来源:互联网 发布:js中des加密解密 编辑:程序博客网 时间:2024/05/16 06:13

“数三退一”游戏规则:
n个人编号0~n-1,手拉手围成一个圈,按照一定的方向从0号开始数,每数到3的人退出,从下一个人继续数,直到剩下最后一个人。
求这个人的编号。

拿数组来模拟,用面向过程的方法...


public class Count3Quit
{
    public static void main(String args[]) {
        int i ,n ,leftNum ,num ;
        n = 500 ;
        boolean[] player = new boolean[n] ;
        for(i=0 ; i<n ; i++) {
            player[i] = true ; 
        }
        leftNum = n ;
        num = 0 ;
        i = 0 ;
        while(leftNum > 1) {
            if(player[i]) {
                num ++ ;
                if(num == 3) {
                    num = 0 ;
                    player[i] = false ;
                    leftNum -- ;
                }
            }
            i ++ ;
            if(i == n)
                i = 0 ;
        }
        for(i=0 ;i<n ;i++) {
            if(player[i])
                System.out.println("No." + i) ;
        }
    }
}

还有一种方法,用面向对象的方法实现模拟...

构建一个玩家(Player)对象和一个圈(Circle)对象,玩家互相拉着手形成一个循环链表。

Cout3Quit2.java

 

class Player
{
    int id ;
    Player left ;
    Player right ;
    Player(int id) {
        this.id = id ;
    }
}

class Circle
{
    int num = 0 ;
    Player first ;
    Player last ;
    Circle(int n) {
        for(int i=0 ;i<n ;i++)
            addPlayer() ;
    }

    public void addPlayer() {
        Player p ;
        if(num == 0) {
            p = new Player(0) ;
            p.left = p ;
            p.right = p ;
            first = p ;
            last = p ;
        }
        if(num > 0) {
            p = new Player(num) ;
            p.left = last ;
            p.right = first ;
            last.right = p ;
            first.left = p ;
            last = p ;
        }
        num ++ ;
    }
    public void delPlayer(Player p) {
        if(num <= 0) {
            return;
        }
        else if(num == 1) {
            first = null ;
            last = null ;
        }
        else {
            p.left.right = p.right ;
            p.right.left = p.left ;
            num -- ;
            if(p.id == first.id) {
                first = p.right ;
            }
            if(p.id == last.id) {
                last = p.left ;
            }
        }
    }
}

public class Count3Quit2
{
    public static void main(String args[]) {
        Circle c = new Circle(500) ;
        Player p ;
        p = c.first ;
        while(c.num > 1) {
            p = p.right.right ;
            c.delPlayer(p) ;
            p = p.right ;
        }
        System.out.println(p.id) ;
    }
}

自己也拿List模拟了这个游戏,和数组的差不多... 

Count3Quit.java 

import java.util.*;
public class Count3Quit{

public static void main(String[] args){

List <Integer>list=new ArrayList();

int n=50;//参加游戏的人数

for(int i=1;i<=n;i++){
 list.add(i);//给每个人一个编号,从1开始,一直到n
 
}
int index=0;//list的下标,用来统计轮到第几个人了,用来循环人数
int num=0;//每个人数的数,为3退出
while(list.size()>1){//当只剩下一个人时退出循环
 num++;//开始数数
 if(num==3){//当数到3时
  list.remove(index);//从list中除去这个元素
  index--;//因为上面减了一个,相应的将list下标提前一个
  num=0;//相应的将数的数归零
 }
 index++;//list下标跳到下一个数数人
 if(index==list.size()){//当list下标等于现有人数时
  index=0;//当list下标归零,使的数数能够循环
 } 
}
System.out.println("最后剩下的小孩是NO."+list.get(0));
    }
}

 

相当经典的一道算法题......

原创粉丝点击