问题描述:

  假设有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 个小孩

 

posted on 2017-04-23 18:04  牧羊人的世界  阅读(267)  评论(0编辑  收藏  举报