有 n个人围成一圈,顺序排号。从第一个人开始报数(从 1 到 3 报数),凡报到 3 的人退出圈子, 问最后留下的是原来第几号的那位

题目:有 n个人围成一圈,顺序排号。从第一个人开始报数(从 1 到 3 报数),凡报到 3 的人退出圈子, 问最后留下的是原来第几号的那位。
分析:
1.圈子人有序号,并且可以循环报数,用数组来存放。
2.圈子人的状态有两种情况,用1和0表示
3.循环报数遇到3就退出,那么最后只会剩下一个人—>这个便是循环条件
4.设置一个计数器,每次有人报数计数器就加1,当计数器加到3时,这个人退出并将这个人状态标记为0


package com.math.forth;

import java.util.Scanner;

/***
 * 题目:有 n个人围成一圈,顺序排号。从第一个人开始报数(从 1 到 3 报数),凡报到 3 的人退出圈子, 问最后留下的是原来第几号的那位。
 * 分析:1.圈子人有序号,并且可以循环报数,用数组来存放。
 * 2.圈子人的状态有两种情况,用1和0表示
 * 3.循环报数遇到3就退出,那么最后只会剩下一个人--->这个便是循环条件
 * 4.设置一个计数器,每次有人报数计数器就加1,当计数器加到3时,这个人退出并将这个人状态标记为0
 * @author wql
 *
 */
public class Math16 {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入数字个数:");
        int n = sc.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i <arr.length; i++) {
            arr[i] = 1;
        }
        method(arr);//方法执行后,此时这个圈子只剩下一个人了
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]==1){
                System.out.println("原位号:"+i);
            }
        }
    }

    /***
     * 实现方法
     * @param arr
     */
    public static void method(int[] arr) {
        int count = 0;//循环三个计数
        int x=arr.length;//标识1的总数
        int i=0;    //数组角标
        while(x>1){
            if(arr[i]==1){
                count++;
            }

            if(count==3){
                arr[i]=0;//遇到数3的人了,退出圈子,标识立马变为0
                x--;    //标记为1的人数少一个
                count=0;//计数器归零,重新计数
            }

            if(i==arr.length-1){
                i=-1;
            }

            i++;//让人动起来
        }
    }
}

运行图


这个题目就是一个约瑟夫环问题,以前做过,但今天看到这个面试题依旧想了好久…想吃xiang的郁闷

约瑟夫环很经典参考:http://blog.csdn.net/qq_36330228/article/details/76408100

原文地址:https://www.cnblogs.com/wangqilong/p/8279764.html