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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© qingxi1 中级黑马   /  2014-8-7 14:21  /  6686 人查看  /  25 人回复  /   3 人收藏 转载请遵从CC协议 禁止商业使用本文

下面有一道入学考试题:
有100个人围成一个圈,从1开始报数,报到14的这个人就要退出。然后其他人重新开始,从1报数,到14退出。问:最后剩下的是100人中的第几个人?
我的写法是:
public class Test {
public static void main(String[] args) {
  ArrayList<Integer> al = new ArrayList<Integer>();
  for(int i = 1; i<=100; i++)//给集合添加元素
   al.add(i);//添加到集合
  ArrayList<Integer> newAl = new ArrayList<Integer>();
  newAl = getQuit();
  al.removeAll(newAl);
  for(Iterator<Integer> it = al.iterator(); it.hasNext();){
   System.out.print(it.next()+" ");
  }
}
private static ArrayList<Integer> getQuit() {
  ArrayList<Integer> newAl = new ArrayList<Integer>();
  int count = 0;
  
  for(int i = 1; i<101; i++){
   count++;
   while(newAl.contains(i)){
    i++;
    if(i==101){
     i = 1;
    }
   }
   if(count%14==0){
    newAl.add(i);
    count = 0;
   }
   if(i==100){
    i=1;
   }
   if(newAl.size()>86)//循环终止条件:当圈子中剩余13个元素,也就是集合里面已经添加了87个就退出循环
    break;
  }
  return newAl;
}
}
在这个程序中,我是认为最后剩下来的是十三个人,就无法在进行数数了,后来和一个朋友交流,他认为最后剩下来的应该是一个人,因为他们一直在循环,不知道那个对,如果剩下一个人,代码应该怎样写;

25 个回复

倒序浏览
List<String> al = new ArrayList<String>();
                for(int i=1;i<=100;i++){
                        al.add("人"+i);
                }
                while(al.size()>1){
                        if(al.size()>=7){
                                al.remove(6);
                        }else{
                                al.remove((7%al.size())-1);
                        }
                }
                System.out.println(al.remove(0));
我是这么想的
回复 使用道具 举报
想错了,刚才以为7个人去一个呢。
                for(int i=1;i<=100;i++){
                        al.add("人"+i);
                }
                while(al.size()>1){
                        if(al.size()>=14){
                                al.remove(13);
                        }else{
                                int size = 14%al.size();
                                if(size==0){
                                        al.remove(al.size()-1);
                                }else{
                                        al.remove((14%al.size())-1);
                                }
                        }
                }
                System.out.println(al.remove(0));
回复 使用道具 举报
刚刚把自己原来的代码重写了下,发现原来可以这么短就能实现。
  1. import java.util.LinkedList;
  2. import java.util.List;

  3. public class Test4 {
  4.         public static void main(String[] args) {
  5.                 game(100, 14);
  6.         }

  7.         public static void game(int person, int num) {
  8.                 List<Integer> list = new LinkedList<Integer>();
  9.                 for (int i = 1; i <= person; i++) {
  10.                         list.add(i);
  11.                 }
  12.                 int pos = 0;
  13.                 while (list.size() > 1) {
  14.                         pos = (pos + num - 1) % list.size();
  15.                         list.remove(pos);

  16.                 }
  17.                 System.out.println(person + "人玩数" + num +
  18.                                 ",最后剩下的是第" + list.get(0) + "人");
  19.         }
  20. }
复制代码

点评

很厉害。  发表于 2016-1-12 09:11
很吊、、、、、、、、、、、、、、、、、大赞!!!!!!!!!!!!!!!!!!  发表于 2014-10-22 11:56
回复 使用道具 举报 3 0
  1. public static void Method() {
  2.                 boolean[] bo = new boolean[100];
  3.                 int count = 0;
  4.                 int leave = 100;
  5.                
  6.                 for (int i = 0; i < bo.length; i++) {
  7.                         if (leave == 1) {
  8.                                 break;
  9.                         }
  10.                        
  11.                         if (bo[i]==false) {
  12.                                 count++;
  13. //                                System.out.println(count);
  14.                                 if (count ==14) {
  15.                                         bo[i] = true;
  16.                                         count = 0;       
  17.                                         leave--;
  18.                                         System.out.println(i);
  19.                                 }
  20.                         }       
  21.                        
  22.                         if (i == bo.length - 1) {
  23.                                 i = -1;
  24.                         }
  25.                 }
  26.                 for (int i = 0; i < bo.length; i++) {
  27.                         if (bo[i]==false) {
  28.                                 System.out.println(i);
  29.                         }
  30.                 }
  31.         }
  32. }
复制代码

我是这么想的,boolean数组100个元素默认都是false,一个计数器,开始数,只要是false,计数器就+1,当到14的时候,就把当前元素变成true,计数器置为0,重新计数,当前是true时,计数器不增加,跳出当前迭代。当数组角标到达99时,重新置为0,再开始。最后剩下一个false就是要求的。

点评

好……  发表于 2014-8-7 19:58
回复 使用道具 举报
你的代码太多了,别人会看的很累啊,大概12行就可以搞定了
回复 使用道具 举报
感觉搞高端的样子呢
回复 使用道具 举报
首先説你这个问题属于    约瑟夫环    百度可以找到很我代码!
我今天写了一个不过和你这个有点小区别     这个数字是连续的不会在一个人出局后从1开始
  1. import java.util.*;
  2. class  Asd
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                 //定义一个ArrayList来存放人  我这里是8个人
  7.                 List<Integer> li= new ArrayList<Integer>();
  8.                 for(int y=1;y<9;y++)
  9.                 {
  10.                         li.add(y);
  11.                 }
  12.                 //count 计数器   记录第个人报的数字,我这个是连续的不是从头来的,和从头来一个样子第下掉一个人初始化就可以了
  13.                 for(int count=1,x=0;li.size()!=1;)
  14.                 {
  15.                         // x是一个角标,一定要最先处理这个,不然可能会出现角标越界
  16.                         if(x==li.size())   // 如果 x=li.size(),角标越界!   这里把角标重新定向到0位置的元素
  17.                         {
  18.                                 x=0;
  19.                         }
  20.                         //数到3的人出局     也是这个数字%3为0   ,因为我的数是连续的所以这里出局一个人角标会变化所以X这里不能处自增
  21.                         if(count%3==0)
  22.                         {
  23.                                 li.remove(x);          
  24.                                 count++;
  25.                         }
  26.                         //如果没有人出局两个变量都要自增
  27.                         else
  28.                         {
  29.                         x++;
  30.                         count++;       
  31.                         }
  32.                 }
  33.                 System.out.println(li);
  34.                 }
  35.                
  36. }
复制代码
回复 使用道具 举报 0 1
好多高手啊= =
回复 使用道具 举报
黎志勇 发表于 2014-8-7 15:19
刚刚把自己原来的代码重写了下,发现原来可以这么短就能实现。

厉害。想法真好。
回复 使用道具 举报
黎志勇 发表于 2014-8-7 15:19
刚刚把自己原来的代码重写了下,发现原来可以这么短就能实现。

赞一个,机智的骚年
回复 使用道具 举报
都这么能敲代码
回复 使用道具 举报
不知道,估计考不上了,:'(
回复 使用道具 举报
大神呀,仔细看看
回复 使用道具 举报
黎志勇 发表于 2014-8-7 15:19
刚刚把自己原来的代码重写了下,发现原来可以这么短就能实现。

报道14的退出后是从第一个开始,还是从第15个啊。还有剩下13个还是循环么?就是到了报13的之后,报14的就成了1了么
回复 使用道具 举报
本帖最后由 375798258 于 2014-9-18 01:56 编辑
  1. package com.itheima;
  2. /*
  3. * 10、 有100个人围成一个圈,从1开始报数,报到14的这个人就要退出。
  4. * 然后其他人重新开始,从1报数,到14退出。问:最后剩下的是100人中的第几个人?
  5. */

  6. import java.util.*;
  7. class Test10 {
  8.         public static void main(String[] args) {
  9.              //定义一个集合1-100
  10.                 ArrayList<Integer> a1=new ArrayList<Integer>();
  11.                 //a2用来存储数到14的a1中第几个下标
  12.                 ArrayList<Integer> a2=new ArrayList<Integer>();
  13.                 //向集合中添加100个元素
  14.               for (int i = 1; i <=100; i++) {
  15.                      a1.add(i);
  16.                                 }
  17.               //初始化 count 计数个数1-14;x下标
  18.               int count=1,x=0;
  19.               while(a1.size()>1){
  20.                     //
  21.                       while(x<a1.size()){
  22.                            
  23.                               //存储被14整除a1的下标
  24.                                         if(count==14){
  25.                                          a2.add(x);count=1; x++;
  26.                                         }else{
  27.                                                 //count记录数到第几个,x记录集合下标
  28.                                                 count++; x++;
  29.                                                 }
  30.                                         }
  31.                       x=0;
  32.                       //删除a1中以a2中元素为下标的元素,从后往前删保证删除正确
  33.                       for (int i = a2.size()-1; i >=0; i--) {
  34.                               int j= a2.get(i);
  35.                                             a1.remove(j);
  36.                                            
  37.                               }  
  38.                       //清楚a2中元素
  39.                       a2.clear();
  40.                   }
  41.                   
  42.               System.out.println(a1.get(0));
  43.         }
  44. }
复制代码

回复 使用道具 举报
学习下!!
回复 使用道具 举报
刚看了一个递归的 发出来给大家看看!
public class Test10 {

        /**
         * 10、 有100个人围成一个圈,从1开始报数,报到14的这个人就要退出。
         * 然后其他人重新开始,从1报数,到14退出。问:最后剩下的是100人中的第几个人?
         */
        public static void main(String[] args) {               
                int s = 0;
                int m = 14;
                for(int i=1; i<=100; i++) {
                s = (s+m)%i;
                }
                System.out.println("最后一个留下来的人是:" + (s+1));
        }
}
回复 使用道具 举报
方法不论好坏,当然能简单巧妙解决问题更好。最关键的是要有自己的想法,思想。。。赞一个!
回复 使用道具 举报
发现这里有好多大神!
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马