问题描述:
假设有500个小孩手拉手围成一圈,从第一个小孩开始数数,按照1、2、3、1、2、3循环不断的数,数到3的小孩退出圈,其他小孩接着数,直到剩下一个小孩,问这个小孩的排在什么位置?
实例分析:
假设有5个小孩,K-K-K-K-K,(用一个字母K表示一个小孩,若某小孩退出了,用Q表示;若某小孩数1,则用1表示该小孩;若某小孩数2,则用2表示该小孩;若某小孩数3,则用3表示该小孩;若小孩还没有数,则仍然用K表示该小孩);
步骤描述:
Step1: K-K-K-K-K
Step1.1: 1-K-K-K-K
Step1.2: 1-2-K-K-K
Step1.3: 1-2-3-K-K
Step1.4: 1-2-3-K-K → K-K-Q-K-K
Step2: K-K-Q-K-K
Step2.1: K-K-Q-1-K
Step2.2: K-K-Q-1-2
Step2.3: 3-K-Q-1-2
Step2.4: 3-K-Q-1-2 → Q-K-Q-K-K
Step3: Q-K-Q-K-K
Step3.1: Q-1-Q-K-K
Step3.2: Q-1-Q-2-K
Step3.3: Q-1-Q-2-3
Step3.4:Q-1-Q-2-3 → Q-K-Q-K-Q
Step4: Q-K-Q-K-Q
Step4.1: Q-1-Q-K-Q
Step4.2: Q-1-Q-2-Q
Step4.3: Q-3-Q-2-Q
Step4.4: Q-3-Q-2-Q → Q-Q-Q-K-Q
结束计算:最后剩下第4个小孩
Java源码:
public class CountThreeQuitOne { public static void main(String[] args) { boolean arr[] = new boolean[500]; // 用数组来表示圈,数组到尾后,回零就行了 for(int i=0;i<arr.length;i++){ arr[i] = true; // 一开始都没有退出,false表示退出 } int index = 0; //指示现在已经数到哪个地方了 int countNum = 0; // 数1,2,3,1,2,3,轮回 int remainNum = arr.length; // 数组除去退出的,还有多少人 while(remainNum > 1) { // 最后剩下一个人,停止 if(arr[index]){ // 只数没有退出的人 countNum ++; if(countNum == 3){ arr[index] = false; countNum = 0; remainNum --; } } index ++ ; if(index == arr.length){ index = 0; } } for(int i=0;i<arr.length;i++){ if(arr[i]){ System.out.println("第 "+(i+1))+" 个小孩"; //由于数组下标是从零开始,故应该剩下第(i+1)个人 } } } }
// 运行结果: 第 436 个小孩