“数三退一”游戏规则:
n个人编号0~n-1,手拉手围成一个圈,按照一定的方向从0号开始数,每数到3的人退出,从下一个人继续数,直到剩下最后一个人。
求这个人的编号。
代码:
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) ;
    }
}红色部分,既然把P从圈中删除了,后面一句还用到p.right这个地方时不是有问题?从Circle.delPlayer(Player p)方法分析,P的right和left还是指向原来的Player,本人认为在删除的时候应该让相应的left和right指向空,才是真正从圈中删除。然后修改相应的算法为
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 Player delPlayer(Player p) {
Player temp;
        if(num <= 0) {
            return null;
        }
        else if(num == 1) {
            first = last = p ;
            return p ;
        }
        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 ;
            }
temp = p.right;
p.left = p.right = null;
return temp;        }
    }
}public class Count3Quit3
{
    public static void main(String args[]) {
        Circle c = new Circle(500) ;
int num = 0;
        Player p ;
        p = c.first ;
        while(c.num > 1) {
num++;
if(num==3){
num = 0;
p = c.delPlayer(p);
} else{           
            p = p.right ;
}
        }
        System.out.println("No." + p.id) ;
    }
}请大虾们指导!!!!

解决方案 »

  1.   

    你确信看懂了下面的代码?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 ; 
       }数三退一,从0开始数的,要退3,中间隔3个,不刚好是right right right么?while(c.num > 1) {
                p = p.right.right ;
                c.delPlayer(p) ;
                p = p.right ;        } 
      

  2.   

    先占个位.这个题我做过的..算法很多..!睡觉.起来再看啦.!呵呵.   锻炼OOP思想是好样的
      

  3.   

    面不面向对象我不清楚了,我写了一个有点通用的,你可以去看看
    http://user.qzone.qq.com/836930375/blog/1239887807
      

  4.   

    看一下Knuth写的 《Concrete Mathmatic (具体数学)》第一章,第三节,讲的Joseph问题,非常透彻。绝对会有醍醐灌顶的感觉的
      

  5.   

    好像你没看懂我的问题,我是说删除P时,是不是让p.left=null、p.right=null ,如果是的话,后面的p=p.right就出错了