zoukankan      html  css  js  c++  java
  • POJ-2746:约瑟夫问题(Java版)

    问题描述:

        题目要求,这里就不再给出了。大致描述如下:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。(2746:约瑟夫问题


    思路分析:

        想做这题,其实是不要想着怎么去循环来报数。要知道,你要是用循环来解,这个循环嵌套是一件很麻烦的事。我不是说循环嵌套麻烦,只是这一题不适合用循环嵌套,关键是谁嵌套谁,还有就是循环结束的地方在哪里?都是问题。所以,这个时候,我们得换一个思路还想问题。我们现在在做的事情只是一循环报数。那要给猴子一个循环吗?是用for循环吗?看到题中的“圈”字就知道这一题肯定是要用到循环,可是关键是循环怎么用的问题。我们可以想到的是,循环还有一个表示方法,那就是周期!其实周期性才是我们解决这一题的关键所在。

    我们需要用到两个周期,一个是猴子的,这个比较明显。还有一个是报数的数组,它也得是一个周期。如果不是周期的,那我们的猴子就只会在退出第一个的时候就停止了,然后就是一个无尽地等待过程(死循环)。


    代码分析:

    两个周期的表示如下:

    indexOfM = (indexOfM + 1 + m) % m;
    
    index = (index + 1 + n) % n;

    还有一点就是这一题用for 循环是不合适的,原因是for循环的第二个参数不太好定。不如用while来得痛快。

    得到下标的关键代码如下:

    private static int getIndexOfKing(int n, int m) {
            int index = 0;
            boolean[] isExit = initBoolean(n);
            
            int indexOfM = 0;
            while (!gotKing(isExit)) {
            	// 如果第i只猴没有退出
            	if(!isExit[index]) {
            		indexOfM = (indexOfM + 1 + m) % m;
            		// 如果第i只猴数到m
                	if(indexOfM == 0) {
                		isExit[index] = true;
                	}
            	}
            	index = (index + 1 + n) % n;
            }
            index = getindexOfKing(isExit);
            
            return (index + 1);
        }

    +1的原因是因为我们代码中的下标是从0开始的,而现实中报数的下标是从1开始的。


    完整代码展示:

    ---------------------------------------完 整 程 序 代 码---------------------------------------------

    import java.util.Scanner;
    
    public class Main {
    
    	/**
    	 * 得到猴王的下标
    	 * @param isExit
    	 * @return
    	 */
    	private static int getindexOfKing(boolean[] isExit) {
    		int index = -1;
    		for (int i = 0; i < isExit.length; i++) {
                if(isExit[i] == false) {
                	index = i;
                	break;
                }
            }
    		
    		return index;
    	}
    	
        /**
         * 是否选出了猴王
         * @param isExit
         * @return
         */
        private static boolean gotKing(boolean[] isExit) {
            int count = isExit.length;
            for (int i = 0; i < isExit.length; i++) {
                if(isExit[i] == true) {
                    count--;
                }
            }
            
            if(count == 1) {
                return true;
            }else {
                return false;
            }
        }
        
        /**
         * 初始化数组
         * @param n
         * @return
         */
        private static boolean[] initBoolean(int n) {
            boolean[] exit = new boolean[n];
            for (int i = 0; i < n; i++) {
                exit[i] = false;
            }
            
            return exit;
        }
        
        /**
         * 获得猴王的下标
         * @param n
         * @param m
         * @return
         */
        private static int getIndexOfKing(int n, int m) {
            int index = 0;
            boolean[] isExit = initBoolean(n);
            
            int indexOfM = 0;
            while (!gotKing(isExit)) {
            	// 如果第i只猴没有退出
            	if(!isExit[index]) {
            		indexOfM = (indexOfM + 1 + m) % m;
            		// 如果第i只猴数到m
                	if(indexOfM == 0) {
                		isExit[index] = true;
                	}
            	}
            	index = (index + 1 + n) % n;
            }
            index = getindexOfKing(isExit);
            
            return (index + 1);
        }
        
        public static void main(String[] args) {
            int n;
            int m;
            Scanner input = new Scanner(System.in);
            
            while (true) {
            	n = input.nextInt();
                m = input.nextInt();
                if((n == 0) && (m == 0)) {
                	break;
                }
                System.out.println("" + getIndexOfKing(n, m));
    		}
            
        }
    
    }
    


  • 相关阅读:
    Javascript中eval解析的json的几种用法
    使用JSONlib简单的转换json操作
    Oracle12c导入scott测试用户(转)
    javascript中隐藏显示的样式表属性
    利用递归级联删除的代码
    递归(c++)(转)
    学习web开发遇到几个细节问题
    AJAX代码格式
    AJAX简介(转)
    算法训练 调和数列问题
  • 原文地址:https://www.cnblogs.com/fengju/p/6336155.html
Copyright © 2011-2022 走看看