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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

5黑马币
50个人围成一圈数到三和三的倍数时出圈,问剩下的人是谁?在原来的位置是多少?

最佳答案

查看完整内容

package com.ming.test.test9999; import java.util.ArrayList; import java.util.List; public class Test1 { static int num; //B 记录每个人叫到的数字 static List a; //记录第一圈 初始1-50的数字 static List b; //记录每一圈的数字为3的倍数的 下角标 static List c; public static void main(String[] args) { init(); int i = 0; print(a, "a"); print(b, "b"); print(c, "c"); while (a.si ...

30 个回复

倒序浏览
package com.ming.test.test9999;

import java.util.ArrayList;
import java.util.List;

public class Test1 {
        static int num;
        //B  记录每个人叫到的数字
        static List<Integer> a;
        //记录第一圈   初始1-50的数字  
        static List<Integer> b;
        //记录每一圈的数字为3的倍数的  下角标
        static List<Integer> c;

        public static void main(String[] args) {
                init();
                int i = 0;
                print(a, "a");
                print(b, "b");
                print(c, "c");
                while (a.size() != 1) {
                        System.out.println(i);

                        find();
                        print(c, "c");
                        delete();
                        resetA();

                        print(a, "a");
                        print(b, "b");
                       
                        i++;
                }
        }
        //重置A的数字
        public static void resetA() {
                for (int i = 0; i < b.size(); i++) {
                        a.add(++num);
                }
        }
        //找到A中数字为3的倍数
        public static void find() {
                for (int i = 0; i < a.size(); i++) {
                        if (a.get(i) % 3 == 0) {
                                //添加记录到C中
                                c.add(i);
                        }
                }
        }
        //初始化
        public static void init() {
                a = new ArrayList<Integer>();
                b = new ArrayList<Integer>();
                c = new ArrayList<Integer>();
                for (int i = 0; i < 50; i++) {
                        a.add(i + 1);
                        b.add(i + 1);
                }
                num = 50;
        }
        //删除  B中的数字。清空A和C
        public static void delete() {
                //从B的最后的值开始删除。否则B的长度会发生变化,导致后面的值删除的位置会发生错误
                for (int i = c.size() - 1; i > -1; i--) {
                        int ii = c.get(i);
                       
                        /////////////////////
                        /*
                         * 其中的方法在这里耽误的时间比较多
                         * 因为,remove(5);
                         * 之前没有解决好,会把B中的5删除,而不是删除下角标为5的元素
                         */
                        b.remove(ii);
                        /////////////////////
                }
                a.clear();
                c.clear();
        }
        //打印
        public static void print(List<Integer> i, String str) {
                System.out.println(str);
                for (int j = 0; j < i.size(); j++) {
                        System.out.print(i.get(j) + " ");
                }
                System.out.println();
        }
}





还望共同讨论更好的方法。楼主5个黑马币给我吧
回复 使用道具 举报
菜鸟撸过看看
回复 使用道具 举报
本帖最后由 ganjx 于 2014-10-22 23:33 编辑
  1. package com.testthree;
  2. public class TestThree {

  3.         public static void main(String[] args) {
  4.                 // TODO Auto-generated method stub
  5.                 TestThree tt =new TestThree();
  6.                 tt.Test();
  7.         }
  8.         //数数的方法
  9.         public void Test()
  10.         {
  11.                 //创建1-50的数组
  12.                 int[]three = new int[50];
  13.                 for(int i =1;i<51;i++)
  14.                 {                       
  15.                         three[i-1]=i;
  16.                 }
  17.                 //
  18.                 int flag =50;//初始总共有50个数
  19.                 int number =0;
  20.                 //只要数量大于3就要一直数下去
  21.                 while(flag>=3)
  22.                 {
  23.                         for(int i =1;i<51;i++)
  24.                         {
  25.                                 if(three[i-1]!=0)//将数过3或3的倍数的跳过
  26.                                 {
  27.                                         number++;
  28.                                         if(number%3==0)//数过3或3的倍数时将基标为0
  29.                                         {
  30.                                                 flag-=1;//每数一次,总数少一个
  31.                                                 three[i-1]=0;
  32.                                         }
  33.                                        
  34.                                 }
  35.                                
  36.                         }
  37.                        
  38.                 }
  39.                 for(int i =1;i<51;i++)
  40.                 {
  41.                         if(three[i-1]!=0)
  42.                         {
  43.                                 System.out.println(i);
  44.                         }
  45.                        
  46.                 }
  47.                
  48.         }       

  49. }
复制代码
  1. <p style="line-height: 30px; text-indent: 2em;"></p>
复制代码

此题主要还是考查我辈的基本功了,我就直接贴代码,最后打印出11,43;

TestThree.zip

617 Bytes, 下载次数: 331

相应的实现代码

评分

参与人数 1黑马币 +5 收起 理由
void + 5 赞一个!

查看全部评分

回复 使用道具 举报
十指紧扣 来自手机 高级黑马 2014-10-23 12:41:05
报纸
厉害…………………………
回复 使用道具 举报
菜鸟飞过,欣赏一下。
回复 使用道具 举报
约瑟夫算法:
  1. public static void main(String[] args) {
  2.                 int n = 50, m = 3;
  3.                 int index = 0;
  4.                 for (int i = 2; i <= n; i++) {
  5.                         index = (index + m) % i;
  6.                 }
  7.                 System.out.println(index + 1);
  8. }
复制代码

其实这个我也不大懂,数学成绩不咋地啊
回复 使用道具 举报
欣赏一下。
回复 使用道具 举报
菜鸟路过看看!!!
回复 使用道具 举报


  1. #include <stdio.h>

  2. int main(int argc, const char * argv[])
  3. {

  4.     // insert code here...
  5.     int p[15]={0}; // 初始化数组
  6.     int n=15; // 剩余人数;
  7.     int i=1; // 报号
  8.     int j=0; // 下标
  9.     while(n>1){
  10.         if(p[j]==0&&i==3){ // 判断报号是否为3,且没有出列的人
  11.             p[j]=1;        // 将其出列
  12.             i=1;           // 报号初始化为1
  13.             n--;           // 剩余人数减1
  14.         }else if(p[j]==0&&i!=3){ // 判断报号不为3,且没有出列的人
  15.             i++;                 // 报号+1
  16.         }
  17.         if(++j==15){             // 数组下标+1,并判断是否越界
  18.             j=0;                 // 下标越界,初始化为0
  19.         }
  20.     }
  21.     for(i=0;i<15;i++){
  22.         if(p[i]==0){
  23.             printf("出卖耶稣的叛徒序号:%d\n",i);
  24.         }
  25.     }
  26.     return 0;
  27. }
复制代码
回复 使用道具 举报
上面是我的方法,你看看怎么样
回复 使用道具 举报
ganjx 发表于 2014-10-22 23:31
此题主要还是考查我辈的基本功了,我就直接贴代码,最后打印出11,43; ...

楼主的意思不是只剩一个人吗。。。
回复 使用道具 举报
ganjx 中级黑马 2014-11-2 17:30:41
13#
邵起 发表于 2014-11-2 09:09
楼主的意思不是只剩一个人吗。。。

谢谢指出问题,第二十二行改为下面的即可,最后输出11
  1. while(flag>=2)
复制代码



回复 使用道具 举报
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. typedef struct LinkNode linkNode;

  4. //创建一个结构体,用来表示每个节点
  5. struct LinkNode {
  6.     //每个节点的编号
  7.     int id;
  8.     //这个节点的下一个的地址
  9.     linkNode *next;
  10. };


  11. int main()
  12. {
  13.     //初始化第一个节点。设置变量当前节点和下一个节点
  14.     linkNode *head = NULL , *tempCurrent,*tempNext;
  15.    
  16.         //创建节点
  17.         //创建第一个节点
  18.         tempCurrent = (linkNode *)malloc(sizeof(linkNode));
  19.         head = tempCurrent;
  20.         head -> id = 1;
  21.         //创建之后的节点
  22.         for (int i = 2; i <= 50; i ++) {
  23.             //分配节点大小
  24.             tempNext = malloc(sizeof(linkNode));
  25.             
  26.             tempNext -> id = i;
  27.             tempCurrent -> next = tempNext;
  28.             tempCurrent = tempNext;
  29.         }
  30.         //循环链表
  31.         tempCurrent -> next= head ;
  32.    

  33.    
  34.     linkNode *replace = head,*temp = NULL;
  35.     //查找要去除的点,直到还剩最后一个点
  36.     while (replace -> next != replace) {
  37.         
  38.         //设置间隔数量,不是间隔数就直接跳过,直到找到间隔数的节点
  39.         for (int j = 1; j < 3; j ++) {
  40.             temp = replace;
  41.             replace = replace -> next;
  42.         }
  43.         
  44.         //去除满足要求的点
  45.         temp -> next = replace -> next;
  46.         
  47.         printf("出局的是 %d\n",replace -> id);
  48.         //释放节点内存
  49.         free(replace);
  50.         //临时变量向后移
  51.         replace = temp -> next;
  52.     }
  53.    
  54.     //找出最后剩下的点
  55.     printf("最后还剩下的是 %d\n",replace -> id);
  56.     return 0;
  57. }
复制代码
C语言写的,望采纳

回复 使用道具 举报
本帖最后由 渐行渐远 于 2014-11-3 22:46 编辑

import java.util.ArrayList;
import java.util.List;
public class ZhuanQuan {

        public static void main(String[] args) {
                //创建数组型队列
                ArrayList<Integer>al=new ArrayList<Integer>();
                for(int i=1;i<=50;i++){
                        al.add(i);//添加元素
                }
                while(al.size()>1){       //剩最后一人时停止
                        for(int j=0;j<3;j++){                                 
                               int x=al.remove(0);//将点到的人取出
                               if(j%3!=2){   
                                        al.add(x); //不是3的倍数再加到队尾
                                }
                        }
                                                
                }
                System.out.println("最后一个人是"+al.get(al.size()-1));
        }

}
回复 使用道具 举报
/*
根据你的需求 这里用到了一个关于数组的 古典游戏“猴子选大王”的算法
参选的人按1 2 3......n编号并按顺序围成一圈,由第K人(这里K可以根据个人要求指定)开始从1报数
报数到达P时跳出圈外,再由下一个人从1开始 如此循环 知道剩下最后一人 这人也就是(猴子选大王算法中的王)我们所需要的人
*/
import javax.swing.JOptionPane

public class PersonKing{
        public static void main(String[] args){
                String s;
                int n, k, p,n1;
               
                s=JOptionPane.showInputDialog("请输入人数的总数");
                n=Integer.parseInt(s);
                n1=n+1;
                s=JOptionPane.showInputDialog("请输入起始报数人的编号");
                k=Integer.parseInt(s);
                s=JOptionPane.showInputDialog("请输入出局数字: ");
                p=Integer.parseInt(s);
                int a[]=new int[n+1];
                a[0]=0;
                System.out.println("\t 出局人的编号: ");
                for(int i=1;i<a.length;i++)
                        a[i]=1;
                for(int i=1;i<=p;i++){
                        if(n==1)
                                break;
                        else if(i==p||i/3==0){
                                n--;
                                i=0;
                                a[k]=0;
                System.out.print(k+" ");

                        }
                        do{
                        k++;
                        k=k%n1;
                        }where(a[k]!=1);
                }       


                System.out.println("\n 最后剩余的人的编号为:"+k);
               
        }
}
回复 使用道具 举报
请楼主仔细看16楼 中我想这个应该是最标准的算法了(猴子选大王算法)
里面你要求是50人 我这里都没规定死 我是基于算法本身,变量不写死。这个方法就可以单独做成类。方便以后调用。也就是说 以后遇到不是人数是50 第3人或3的倍数(也就是被3整除=0)出局的时候 可以套用。。这是个公式。。就跟真理是已经经过多代人验证过一样,与其说是帮你解决这问题 不如说是教你认识一种前人验证好了的方法,我们要记住以后遇到类似的问题 不用去研究新算法 改怎么实现,直接拿过来套用 笔着  葫芦画瓢,节省时间久是节省金钱

评分

参与人数 1黑马币 +6 收起 理由
void + 6

查看全部评分

回复 使用道具 举报
路过看看
回复 使用道具 举报
本帖最后由 yuanlingqi 于 2014-11-8 13:49 编辑

50个人围成一圈,形成一个闭环,这个一个典型的链表结构,每次出圈,只要把出圈人的左右对接即可,链表最后剩下的那个人,就是你想要的。不多说上代码:
  1. //先要有个用户,包含三个属性
  2. package cn.csdn.test;

  3. public class User {
  4.     /**
  5.      * 用户id
  6.      */
  7.         private int userId;
  8.         /**
  9.          * 下个用户
  10.          */
  11.         private User next;
  12.         /**
  13.          * 上个用户
  14.          */
  15.         private User pre;
  16.        
  17.         public User(int no) {
  18.                 this.userId = no;
  19.         }
  20.         public int getUserId() {
  21.                 return userId;
  22.         }
  23.         public void setUserId(int userId) {
  24.                 this.userId = userId;
  25.         }
  26.         public User getNext() {
  27.                 return next;
  28.         }
  29.         public void setNext(User next) {
  30.                 this.next = next;
  31.         }
  32.         public User getPre() {
  33.                 return pre;
  34.         }
  35.         public void setPre(User pre) {
  36.                 this.pre = pre;
  37.         }
  38. }
复制代码
2.游戏开始
  1. package cn.csdn.test;
  2. import cn.csdn.test.User;
  3. public class GamePlay {
  4.         
  5.         /**
  6.          * 出圈数数
  7.          */
  8.         private static int OUTNUMBER = 3;
  9.         /**
  10.          * 玩游戏的人数
  11.          */
  12.         private static int USERCOUNT = 5;
  13.         
  14.         public static void main(String[] args) {

  15.                 if(USERCOUNT <= 0 || OUTNUMBER <= 0) {
  16.                         System.out.println("你逗我?");
  17.                         System.exit(-1);
  18.                 }
  19.                
  20.                 //1.将50个人围成一圈,构成单向链表结构
  21.                 User firstUser = null,curUser = null,newUser = null;
  22.                 for(int i=1; i<=USERCOUNT;i++){
  23.                         newUser = new User(i);
  24.                         if(firstUser == null){
  25.                                 firstUser = newUser;
  26.                                 curUser = newUser;
  27.                         }else{
  28.                                 newUser.setPre(curUser);
  29.                                 curUser.setNext(newUser);
  30.                                 curUser = newUser;
  31.                         }
  32.                 }
  33.                 //形成闭环
  34.                 curUser.setNext(firstUser);
  35.                 firstUser.setPre(curUser);
  36.                
  37.                 //2.从头开始遍历链表,数到3的人出链表,再将出圈人的左右两人对接
  38.                 User temp = firstUser;
  39.                 int i = 1;
  40.                 do{
  41.                         if(temp != null && i % OUTNUMBER == 0){
  42.                                 User pre = temp.getPre();
  43.                                 User next = temp.getNext();
  44.                                 if(next == pre) {
  45.                                         temp = next;
  46.                                         break;
  47.                                 }
  48.                                 pre.setNext(next);
  49.                                 next.setPre(pre);
  50.                                 temp = next;
  51.                                 i=1;
  52.                         }else{
  53.                                 temp = temp.getNext();
  54.                                 i++;
  55.                         }
  56.                 }while(true);
  57.                 System.out.println("共有"+ USERCOUNT + "玩家,最后留在圈的人是  " + temp.getUserId());
  58.         }
  59. }
复制代码




回复 使用道具 举报
yuanlingqi 发表于 2014-11-8 13:42
50个人围成一圈,形成一个闭环,这个一个典型的链表结构,每次出圈,只要把出圈人的左右对接即可,链表最后 ...

从1开始编号和数数,50人最后剩下的是11号
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马