• 【编程题】约瑟夫环及约瑟夫变种问题


    约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。

     1 package MyTest;
     2 
     3 /**
     4  * 约瑟夫环的问题
     5  * @author Administrator
     6  *
     7  */
     8 import java.util.*;
     9 public class JosephCircle {
    10 
    11     public static void main(String[] args) {
    12         Scanner in = new Scanner(System.in);
    13         while(in.hasNext()){
    14             int peopleNum = in.nextInt();
    15             int k = in.nextInt();
    16             joseph(peopleNum, k);
    17         }
    18         in.close();
    19 
    20     }
    21 
    22     private static void joseph(int peopleNum, int k) {
    23         //初始化人的ID
    24         List<Integer> circle = new LinkedList<>();
    25         for(int i =1; i <= peopleNum; i++){
    26             circle.add(i);
    27         }
    28         
    29         //从第flag个开始计数
    30         int flag = 0;
    31         while(circle.size() > 0){
    32             flag = flag + k;
    33             
    34             //第k个人的索引位置
    35             flag = flag % (circle.size()) - 1; //这个可以实现循环!!!!
    36             
    37             //判断是否到队尾,处理特殊情况,把flag置0
    38             if(flag < 0){
    39                 System.out.println(circle.get(circle.size()-1));
    40                 circle.remove(circle.size() -1);
    41                 flag = 0;
    42             }
    43             else{
    44                 System.out.println(circle.get(flag));
    45                 circle.remove(flag);
    46             }
    47         }
    48     }
    49 
    50 }

    约瑟夫环变种: 
    输入一个由随机数组成的数列(数列中每个数均是大于0的整数,长度已知),和初始计数值m。从数列首位置开始计数,计数到m后,将数列该位置数值替换计数值m,并将数列该位置数值出列,然后从下一位置从新开始计数,直到数列所有数值出列为止。如果计数到达数列尾段,则返回数列首位置继续计数。请编程实现上述计数过程,同时输出数值出列的顺序

    比如: 输入的随机数列为:3,1,2,4,初始计数值m=7,从数列首位置开始计数(数值3所在位置)
    第一轮计数出列数字为2,计数值更新m=2,出列后数列为3,1,4,从数值4所在位置从新开始计数
    第二轮计数出列数字为3,计数值更新m=3,出列后数列为1,4,从数值1所在位置开始计数
    第三轮计数出列数字为1,计数值更新m=1,出列后数列为4,从数值4所在位置开始计数
    最后一轮计数出列数字为4,计数过程完成。
    输出数值出列顺序为:2,3,1,4。

    • 要求实现函数: 
    void array_iterate(int len, int input_array[], int m, int output_array[])
    【输入】 int len:输入数列的长度;
    int intput_array[]:输入的初始数列
    int m:初始计数值
    【输出】 int output_array[]:输出的数值出列顺序
    【返回】 无

    • 示例 
    输入:int input_array[] = {3,1,2,4},int len = 4, m=7
    输出:output_array[] = {2,3,1,4}

     1 package MyTest;
     2 
     3 /**
     4  * 约瑟夫环变种问题
     5  * @author Administrator
     6  *
     7  */
     8 
     9 import java.util.*;
    10 
    11 public class JosephPro {
    12     
    13     static LinkedList<Integer> result = new LinkedList<>();
    14     public static void main(String[] args) {
    15         Scanner in = new Scanner(System.in);
    16         while(in.hasNext()){
    17             result.clear();
    18             int len = in.nextInt();
    19             int[] input_aray = new int[len];
    20             for(int i = 0; i < len; i++){
    21                 input_aray[i] = in.nextInt();
    22             }
    23             int m = in.nextInt();
    24             josephIterate(len, input_aray, m);
    25             for(Integer o: result){
    26                 System.out.println(o);
    27             }
    28         }
    29         in.close();
    30 
    31     }
    32 
    33     private static void josephIterate(int len, int[] input_aray, int m) {
    34         LinkedList<Integer> array = new LinkedList<>();
    35         for(int i = 0; i < len; i++)
    36             array.add(input_aray[i]);
    37         int flag = 0;
    38         while(array.size() > 0){
    39             flag = flag + m;
    40             int i = flag % array.size() -1;
    41             
    42             if(i<0){
    43                 m = array.get(array.size()-1);
    44                 result.add(array.get(array.size()-1));
    45                 array.remove(array.size()-1);
    46                 flag = 0;
    47             }
    48             else{
    49                 m = array.get(i);
    50                 flag = i;    //这个很重要 要及时更新开始位置flag
    51                 result.add(array.get(i));
    52                 array.remove(array.get(i));
    53             }
    54             
    55         }        
    56     }
    57 
    58 }

    注意区别一个间隔是固定的,一个是变化的。

  • 相关阅读:
    JS_Boolean Logic
    js String
    .Net之路(二)简介
    自考 操作系统概论计算机系统
    IT大学生最重要的五个能力
    数据库表及字段命名规范
    简述MVC分层
    .Net之路(一)概述
    设计模式(4)迭代器模式
    .Net之路(三)如何连接数据库?
  • 原文地址:https://www.cnblogs.com/focusonepoint/p/5756773.html
Copyright © 2020-2023  润新知