50 个人围成一圈,从1 开始数数,数3 或 3 的倍数的人除去,剩下的人接着数,直到不再有人剔除。打印剩下人的编号。

解决方案 »

  1.   

    约瑟夫算法:n个人围成一圈,每人有一个各不相同的编号,选择一个人作为起点,然后顺时针从1到k数数,每数到k的人退出圈子,圈子缩小,然后从下一个人继续从1到k数数,重复上面过程。求最后推出圈子的那个人原来的编号。
    这个应该比较好实现的,不过要追求一下完美难度就有点大了,呵呵....
      

  2.   

    谭的C语言程序设计上好像有这个程序,可以看看,然后改成JAVA的就可以了,思想都是一样的
      

  3.   

    给你提供一个方法吧,完全的面向对象的思路,我也是学习来的:
    public class Count3Quit2 {
    public static void main(String[] args) {
    KidCircle kc = new KidCircle(50);
      int countNum = 0;
      Kid k = kc.first;
      while(kc.count>1) {
       countNum ++;
        if(countNum == 3) {
       countNum=0;
       kc.delete(k);
       }
      k = k.right;
      }   System.out.println(kc.last.id);
    }
    }class Kid {
       int id;
       Kid left;
       Kid right;
    }class KidCircle {
    int count = 0;
    Kid first,last;

    KidCircle(int n) {
    for(int i=0;i<n;i++) {
    add();
    }
    }

    void add() {
    Kid k = new Kid();
    k.id = count;
    if(count <= 0){
    first = k;
    last = k;
    k.left = k;
    k.right = k;
    } else {
    last.right = k;
    k.left = last;
    k.right = first;
      first.left = k;
      last = k;
    }
    count++;
    }

    void delete(Kid k) {
    if(count<=0) {
    return;
    }else if (count == 1) {
    first = last = null;
    }else {
    k.left.right = k.right;
    k.right.left = k.left;

    if(k == first) {
      first = k.right;
    }else if(k == last) {
      last = k.left;
    }
    }
       count --;
    }
    }
      

  4.   

    import java.util.ArrayList;public class CountDemo { public static void main(String[] args) {
    int num = 50;
    int stepLen = 3;

    ArrayList arr = new ArrayList();
    for(int i=0; i<num; i++) {
    arr.add(i+1);
    }

    int curr = 0;
    for(int i=0; i<arr.size(); i++) {
    if(arr.size() < stepLen)
    break;

    Object n = arr.get(i);
    if(++curr == stepLen) {
    arr.remove(n);
    curr = 0;
    i--;
    }
    if(i == arr.size()-1)
    i = 0;
    } System.out.println("------result-------");
    for(Object last : arr) {
    System.out.println(last);
    }
    }}
      

  5.   

    昨天写错了,剩下的应该是一个人,我的结果是 1.import java.util.ArrayList;
    public class CountDemo {
    public static void main(String[] args) {
    int num = 50;
    int stepLen = 3;

    ArrayList arr = new ArrayList();
    for(int i=0; i<num; i++) {
    arr.add(i+1);
    }

    int curr = 0;
    for(int i=0; i<arr.size(); i++) {
    if(arr.size() == 1)
    break;

    Object n = arr.get(i);
    if(++curr == stepLen) {
    System.out.println(n + " out");
    arr.remove(n);
    curr = 0;
    i--;
    }
    if(i == arr.size()-1)
    i = 0;
    }
    System.out.println("剩下的人的编号是:" + arr.get(0));
    }
    }
      

  6.   

    我是按一楼的说法写的代码:
    public static void countDemo(int count) {
    List<Integer> list1 = new ArrayList<Integer>(count);
    List<Integer> list2 = new ArrayList<Integer>();
    for (int i = 1; i <= count; i++) {
    list1.add(i);
    } int i = 1;
    while (list1.size() > 0) {
    if (i % 3 == 0) {
    list2.add(list1.get(0));
    list1.remove(0);
    } else {
    int j = list1.get(0);
    list1.remove(0);
    list1.add(j);
    }
    i++;
    }
    System.out.println("the sequence:");
    for (Integer m : list2) {
    System.out.println(m);
    }
    }传递的参数是7:
    下面是输出结果:
    the sequence:
    3
    6
    2
    7
    5
    1
    4
      

  7.   

    public int getLucky(int[] arr){
    int pos = -1;
    int luck = 0;
    for(int x=0; x<arr.length-1; x++){
    for(int y=0; y<3; y++){
    pos++;
    if(pos==arr.length)
    pos = 0;
    while(arr[pos]==0){
    pos++;
    if(pos==arr.length){
    pos = 0;
    }
    }
    }
    arr[pos] = 0;
    }
    for(int x=0; x<arr.length; x++){
    if(arr[x]!=0){
    luck = arr[x];
    break;
    }
    }
    return luck;
    }
      

  8.   

    写了一个,是按照这样写的,如果剩下2个人就不数了,直接返回这两个人的编号。
    public class YueSeFu {
    public static void main(String[] args) {
    int[] re = getLast(50, 3);
    for (int k = 0; k < re.length; k++) {
    System.out.println(re[k]);
    }
    } public static int[] getLast(int count, int mubiao) {
    // count 原来人数,mubiao 数到要淘汰的数
    int counts = count;
    int[] result = new int[mubiao - 1];//返回比mubiao少1的原编号的数组
    int[] all = new int[count];// 初始化总人数的编号
    for (int i = 1; i <= count; i++) {
    all[i - 1] = i;
    }

    int i = 1;
    int j = 0;
    // 当剩下的人数比mubiao少时退出循环
    while (counts >= mubiao) {
    // 对数到目标数且不为0的数赋0,
    if (i % mubiao == 0 && all[j] != 0) {
    // 对数到mubiao数的人赋0
    all[j] = 0;
    counts--;
    i = 1;
    } else if (all[j] != 0) {
    i++;
    }
    //增加下标 若到最后一个则从0开始
    if (j == count - 1)
    j = 0;
    else
    j++;
    }
    //把剩下的人放到返回数组中
    for (int k = 0, m = 0; k < count; k++) {
    if (all[k] != 0) {
     result[m] = all[k];
     m++;
    }
    }
    return result;
    }
    }
    运行结果是11和43
      

  9.   

    这个题目最好的解决方案是拿ArrayList做,当时我初学Java的时候老师给了些编程题,里面有这个,,我当时还没学到集合.所以拿数组做了个程序..现在呈上来,可以看下.我觉得还勉强过得去..!呵呵 希望高手指点public static void deleteNum(int n)//参数n为参加游戏的人数
    {
    int a[]=new int[n];//声明长度为n的数组,并全部为默认值0
    int t=0;//这个t是表示报数的
    int i;
    int count=0;//记数,,看有多少人被踢出去了
    for (i = 0; i < a.length; i++) {
    if(a[i]==1)//如果a[i]==1,则跳出继续下一次
    continue;
    else
    {
    t++;//报数
    if(t==3)//判断是否报到3了
    {
                                            //报到3了就把a[i]设置成1,报数清0,记数加1
    a[i]=1;
    t=0;
    count++;
    }
    if(count==a.length)//如果记数等于数组长度了就跳出循环
    break;
    if(i==a.length-1)//如果到数组最后一个人了,则从第⒈个人继续开始报.!
    i=-1;
    }
    }
                    System.out.println("剩下的一个人是原来的第"+(i+1)+"号");数组中所有0的人表示还在的.1的表示已经被踢的..  
      

  10.   

    "直到不再有人剔除"感觉有点模糊,我的理解是最后只剩下一个人
    我的算法是在的人是“1”被提出的人是“2”
    结果:2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
    public class Sort { public static void main(String[] args) {
            new Sort().print(); 
    }
    public void print() {
    //总人数
    int[] total = new int[50];
    for(int i = 0; i<50;i++) {
    total[i] = 1;
    }
    int number = 0;
    int n = 0;
    int j = 0;
    while(!isOk(total)) {
    if(j==50) {
    j=0;
    }
    number++;
    if(total[j]==2) {
    number--;
    j += 1;
    continue;
    }
    if(number%3==0) {
    total[j] = 2;
    }
    j++;
    }
    for(int i:total) {
    System.out.print(" "+i);
    }
    }
    public boolean isOk(int total[]) {
    int num = 0;
    for(int i = 0; i<50;i++) {
    if(total[i] == 2) {
    num++;
    }
    }
    //要踢出的人数
    if(num==49) {
    return true;
    } else {
    return false;
    }
    }
    }
      

  11.   

    最后应该只剩下一个人的吧。给我写的代码,交流一下public class Count { /**
     * @param args
     */
    public static void main(String[] args) {
    new Count().run();
    } public void run() {
    ArrayList<Integer> arr = new ArrayList<Integer>(50);
    // 初始编号1至50
    for (int i = 1; i <= 50; i++) {
    arr.add(i);
    }
    int count = 0;// 计数值
    while (arr.size() > 1) {//最后只剩下1个人了
    //数到3或3的倍数时赋值为0(做记号)
    for (int i = 0; i < arr.size(); i++) {
    if (++count % 3 == 0) {
    arr.set(i, 0);
    }
    }
    //将记号为0的值从列表中删除
    for (int i = 0; i < arr.size(); i++) {
    if (arr.get(i) == 0)
    arr.remove(i);
    }
    }
    // 输出剩下结果
    for (int x : arr) {
    System.out.println("最后剩下的人的编号为:" + x);
    }
    }}
      

  12.   

    25#算法很好。
    我也给一个:import java.util.ArrayList;
    import java.util.List;public class CycleGameLM
    {
    private static List<Integer> afterList = new ArrayList<Integer>(); public static void main(String[] args)
    {
    int total = 10;
    int split = 3; for (int i = 1; i <= total; i++)
    {
    afterList.add(i);
    } while (true)
    {
    int size = afterList.size();
    if (size != 1)
    {
    int index = split % size;
    if (index == 0)
    {
    System.out.println(String.valueOf(afterList.get(size - 1)));
    afterList.remove(size - 1);
    afterList = makeAfterList(size);
    }
    else
    {
    System.out.println(String.valueOf(afterList.get(index - 1)));
    afterList.remove(index - 1);
    afterList = makeAfterList(index);
    }
    }
    else
    {
    System.out.println(String.valueOf(afterList.get(0)));
    break;
    }
    }
    } private static List<Integer> makeAfterList(int index)
    {
    List<Integer> list = new ArrayList<Integer>(); for (int a = index - 1; a < afterList.size(); a++)
    {
    list.add(afterList.get(a));
    }
    for (int b = 0; b < index - 1; b++)
    {
    list.add(afterList.get(b));
    }
    return list;
    }
    }基本思想是,每找到一个数并删除后,重组List。