A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 中国移动 黑马帝   /  2012-7-20 15:07  /  3527 人查看  /  12 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

思路:
先把人的编号存储在一数组里面,然后找到第一个开始报数的人,然后把第一个报数的人利用数组排序把他掉到前面去,然后开始报数,在把报到特定数的后面的元素往前移一位,一直到把所有的数储存到另外一个数组。
可以用各种语言写,只要原理对了就行!

点评

继续支持中国移动3分  发表于 2012-7-20 15:12

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

12 个回复

倒序浏览
帮你编辑了

点评

感谢滔哥,感谢黑马传说中的滔哥,滔哥是俺的偶像啊!  发表于 2012-7-20 23:24
回复 使用道具 举报
方法:可以用数组来存放N个数,相当于N个数排成的圈;用整型变量指向当前数到的数组元素,
相当于人的手指;划掉一个数的操作,就用将一个数组元素置0的方法来实现。人工数的时候,要跳过已
经被划掉的数,那么程序执行的时候,就要跳过为0的数组元素。注意,当指向当前数到的数组元素的整
型变量指向数组中最后一个元素(下标为N-1)时,再数下一个,则该整型变量要指回到数组的第一个元
素(下标为0),这样才像一个圈。
  1. import java.util.LinkedList;
  2. import java.util.List;
复制代码
  1. /**
  2. * 约瑟夫环问题的一种描述是:编号为1.2.3…….n的n个人按顺时针方向围坐一圈 ,每人手持一个密码(正整数),
  3. * 开始任意选一个整数作为报数上限值,从第一个人开始顺时针自1开始顺序报数,报到m时停止报数。报m的人出列,
  4. * 将他的密码作为新的m值,从他顺时针下一个人开始重新从1开始报数,
  5. * 如此下去直到所有的人全部都出列为止。试设计程序实现,按照出列的顺序打印各人的编号。
  6. * @author Administrator
  7. *
  8. */
  9. public class Question2 {
  10. class person {
  11. int password;
  12. int number;
  13. int state = 1;

  14. public person(int password, int number) {
  15. this.password = password;
  16. this.number = number;
  17. }
  18. public person(int number){
  19. this.number = number;
  20. }
  21. }

  22. public int ListLength(List<person> list) {
  23. int count = 0;
  24. if (list != null) {
  25. for (person p : list) {
  26. if (p.state != 0) {
  27. count++;
  28. }
  29. }
  30. }
  31. return count;
  32. }

  33. public void cacle() {
  34. // 初始化数据
  35. List<person> list = new LinkedList<person>();
  36. list.add(new person(3,1));
  37. list.add(new person(1,2));
  38. list.add(new person(7,3));
  39. list.add(new person(2,4));
  40. list.add(new person(4,5));
  41. list.add(new person(8,6));
  42. list.add(new person(4,7));

  43. int position = -1;//初始位置
  44. int m = 20; //第一次报多少的人出来
  45. int count = 0;//已经报了多少人
  46. while (ListLength(list) != 0) {

  47. position = (position + 1) % list.size();// 位置定位

  48. if (((person) list.get(position)).state != 0) {
  49. count++;
  50. }
  51. if (count == m) {
  52. person p = list.get(position);
  53. System.out.print(p.number+" ");
  54. p.state = 0;
  55. m = p.password;
  56. list.set(position, p);
  57. count = 0;
  58. }
  59. }


  60. }
  61. public static void main(String[] args) {
  62. Question2 q= new Question2();
  63. q.cacle();
  64. }

  65. }

复制代码

点评

帮你编辑了,这样不是好看多了吗?  发表于 2012-7-21 00:03

评分

参与人数 1技术分 +3 收起 理由
滔哥 + 3 不错,有思路

查看全部评分

回复 使用道具 举报

  1. public class Test {
  2.         
  3.         public static int[] Joshphus(int start,int step,int size){        //start:从第几个人开始,step:报多少数走一个,size:一共多少人
  4.                 int[] arInt=new int[size];
  5.                 //1.初始化数组,把每个人编上号
  6.                 for(int i=0;i<size;i++)
  7.                         arInt[i]=i;
  8.                 //2.先把开始报数的人挪到最前面的位置,就是arInt[0]
  9.                 for(int i=start;i!=0;i--){
  10.                         int temp=arInt[0];
  11.                         for(int j=0;j<size;j++){
  12.                                 if(j!=size-1)
  13.                                         arInt[j]=arInt[j+1];
  14.                                 else
  15.                                         arInt[j]=temp;
  16.                         }
  17.                 }
  18.                 //3.开始报数
  19.                 int currentSize=size;                        //还剩多少人
  20.                 int p=0;                                                //该第几个人报数了
  21.                 int num=1;                                                //报数报到几了
  22.                
  23.                 while(currentSize>0){
  24.                         if(num==step){                                //报到step,这哥们出列了
  25.                                 int temp=arInt[p];          //出列的哥们要放到数组最后,先把他存起来
  26.                                 for(int i=p;i<size-1;i++)
  27.                                         arInt[i]=arInt[i+1];
  28.                                 arInt[size-1]=temp;
  29.                                 num=1;
  30.                                 if(p==--currentSize)        //这里p就不用前移了,因为后面的人已经自动顶上来了
  31.                                         p=0;                                //但是p指向最后一个的话,要把p挪到最前面去
  32.                         }else{                                                //还没报到step
  33.                                 num++;
  34.                                 if(++p==currentSize)
  35.                                         p=0;
  36.                         }
  37.                 }        
  38.                 return arInt;
  39.         }
  40.         
  41.         public static void main(String[] args){
  42.                 int[] arInt=Joshphus(2,3,7);
  43.                 for(int i:arInt)
  44.                         System.out.print(i+" ");
  45.         }
  46.         
  47. }
复制代码
回复 使用道具 举报
去掉每一个元素后还是一个约瑟夫环,所以,可以使用递归实现,网上相关的代码很多,这个就还可以,http://zhidao.baidu.com/question/260915453.html
回复 使用道具 举报
先占个楼 晚点写代码

点评

唉 ,你晚点写,这贴又要被滔哥给关闭了  发表于 2012-7-20 23:25
回复 使用道具 举报
  1. package cn.itcast.demo;

  2. import java.util.*;

  3. public class ThreePointDemo {

  4.         public static void main(String[] args)
  5.         {
  6.                 int dropNumber=0;
  7.                 int count=0;
  8.                 List<String> list=new LinkedList<String>();
  9.                 for(int number=1;number<=12;number++)//这里设置你要存入多少人;
  10.                 {
  11.                         list.add("person number:"+number);
  12.                 }       
  13.                 while(list.size()!=0)//核心程序代码
  14.                 {
  15.                         if(count==4)//这里设置你要的报号的数字我设置的为4;
  16.                         {
  17.                                 int midparam=--dropNumber;
  18.                                 if(midparam<0)
  19.                                 {
  20.                                         midparam=list.size()-1;
  21.                                 }                               
  22.                                 System.out.println("the drop number is : number"+list.remove(midparam));
  23.                                 count=0;
  24.                                 print(list);
  25.                                 System.out.println();
  26.                         }
  27.                         count++;
  28.                         dropNumber++;
  29.                         if(list.size()==0)break;
  30.                         dropNumber=dropNumber%list.size();

  31.                 }
  32.        
  33.         }
  34.         public static void print(List<String> list)//为了打印方便做的函数print
  35.         {
  36.                 for(Iterator it=list.iterator();it.hasNext();)
  37.                 {
  38.                         System.out.print(it.next());
  39.                 }
  40.                
  41.         }
  42. }
复制代码
要是c程序的话,还比较行,用习惯指针了,java的逻辑就有点冗余了。结果如图:

(`I%[6PFL7C)M}GW}NWXAUD.jpg (127.42 KB, 下载次数: 125)

(`I%[6PFL7C)M}GW}NWXAUD.jpg

评分

参与人数 1技术分 +3 收起 理由
滔哥 + 3 确实,用C写算法比较好写点,等下我甩用C#.

查看全部评分

回复 使用道具 举报

public class MainClass {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                int[] src ={1,2,3,4,6,5,7};
                int[] dest = new int[src.length];
                numOff(src,dest,3);
        }
        /**
         *
         * @param source 原报数编号数组
         * @param dest 新报数编号数组
         * @param remove  特定的号数
         */
        public static void numOff(int[] source,int[] dest,int remove){
                int[] src = source;
                int[] des = dest;
                int i = 0;
                int k = 0;
                int length = src.length;
                int d = 0;
                while(length>=1){
                        if(i==length){
                                i=0;
                        }
                        k++;
                        if(k!=remove){
                                i++;
                                continue;
                        }
                        //报到特定的号数时,把这个编号赋值到新的数组
                        if(k==remove){
                                des[d] = src[i];
                                //特定号数后面的元素向前移动
                                for(int a = i;a<src.length;a++){
                                        if(a+1==src.length){
                                                break;
                                        }
                                        src[a]=src[a+1];
                                }
                                d++;
                                k=0;//剩下的人重新报号
                                length--;//每有一个报特定号数,数组长度的值减一
                        }
                       
                }
        }
}
应该是这样的吧?!

评分

参与人数 1技术分 +3 收起 理由
滔哥 + 3 勉强把

查看全部评分

回复 使用道具 举报
滔哥 黑马帝 2012-7-20 22:51:18
9#
  1. Console.WriteLine("请输入参与游戏的人数:");
  2. int numPerson = int.Parse(Console.ReadLine());//读取转换赋予

  3. Console.WriteLine("请输入游戏退出的规则数:");
  4. int ruleNum = int.Parse(Console.ReadLine());//读取转换赋予

  5. bool[] person = new bool[numPerson]; //定义每个人是否退出开关,默认为否
  6. int callNum = 0; //报数
  7. int total = 0; //记录已经退出的人数
  8. int index = -1; //报数的循环游标

  9. while (true) {

  10. index++; //从第一个人开始
  11. index %= numPerson; //确保数组不越界,当游标指向最后一个数组元素以后,从头开始

  12. if (!person[index]) { //第index个人没有退出时,则进行报数

  13. callNum++;
  14. }
  15. if (callNum == ruleNum) { //当第index个人报数的数字与规则数相同时,则开关打开,退出报数

  16. person[index] = true;
  17. total++; //退出的总人数更新
  18. callNum = 0; //为下一个人报数更新数据
  19. Console.WriteLine("玩家{0}退出",index+1);
  20. }
  21. if ((numPerson - total) == 1) { //当游戏玩家只剩下一个的时候结束游戏

  22. for (int i = 0; i < person.Length; i++) {

  23. if (person[i] == false) { // 判断退出开关依然是否的玩家

  24. Console.WriteLine("最后剩下的玩家是第:{0}位",i + 1); //输出实际的玩家号
  25. break;
  26. }
  27. }
  28. break;
  29. }
  30. }
复制代码
C#选手,菜鸟了,别怪啊,呵呵
回复 使用道具 举报
好久以前的一道作业题,...记得那时候是使用C语言的链表来做的.
回复 使用道具 举报
package testSomething;

import java.util.Scanner;

/**
* 先把人的编号存储在一数组里面,然后找到第一个开始报数的人,然后把第一个报数的人利用数组排序把他掉到前面去,然后开始报数,
* 在把报到特定数的后面的元素往前移一位,一直到把所有的数储存到另外一个数组。 可以用各种语言写,只要原理对了就行!
*/
public class JSF {
        public static void main(String[] args) {
                while (true) {
                        System.out.println("请输入总数:输入0结束");
                        Scanner sca = new Scanner(System.in);
                        int m = sca.nextInt();
                        if (m == 0) {
                                System.out.println("结束");
                                System.exit(0);
                        }
                        System.out.print("请输入报数周期:\n");
                        int n = sca.nextInt();
                        System.out.print("按出圈的次序输出序号:\n");

                        int[] a = new int[m];
                        int len = m;
                        for (int i = 0; i < a.length; i++)
                                a[i] = i + 1;
                        // i为元素下标
                        int i = 0;
                        // j代表当前要报的数
                        int j = 1;
                        while (len > 0) {
                                // 以m为周期的一个循环,在数组中按m周期不停报数
                                int t = i % m;
                                if (a[t] > 0) {
                                        int w = j % n;
                                        if (w == 0) {// 找到要出圈的人,并把圈中人数减一
                                                System.out.print(a[t] + "  ");
                                                a[t] = -1;
                                                j = 1;
                                                i++;
                                                len--;
                                        } else {
                                                i++;
                                                j++;
                                        }
                                } else {// 遇到空位了,就跳到下一位,但j不加一,也就是这个位置没有报数
                                        i++;
                                }
                        }
                        System.out.println();
                }
        }
}

点评

感谢你们,感谢黑马的大牛们,我爱你们  发表于 2012-7-20 23:46

评分

参与人数 1技术分 +3 收起 理由
滔哥 + 3 赞一个!

查看全部评分

回复 使用道具 举报
黑马高明辉 发表于 2012-7-20 23:33
package testSomething;

import java.util.Scanner;

哥,分!
回复 使用道具 举报
滔哥 黑马帝 2012-7-20 23:56:29
13#
任务已经解决,锁帖
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马