首页 > 试题广场 >

约瑟夫环

[编程题]约瑟夫环
  • 热度指数:17977 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt}n 个人(编号 0\sim n-1)围成一圈,从编号为 k 的人开始报数,报数依次为 1,2,\dots,m,报到 m 的人出队。下次从出队者的下一个人开始重新报数,循环往复,直到队伍中只剩最后一个人,该人即"大王"。

\hspace{15pt}给定三个正整数 n,k,m,请输出最后剩下的"大王"编号。

输入描述:
\hspace{15pt}在一行中输入三个整数 n\left(2 \leqq n \leqq 100 \right),k\left(0 \leqq k \leqq n-1\right),m\left(1 \leqq m \leqq 100\right),用空格隔开。


输出描述:
\hspace{15pt}输出一个整数,表示最后剩下的"大王"编号。
示例1

输入

5 1 2

输出

3

说明

初始队列编号为 [0,1,2,3,4],从编号 1 开始报数:

\hspace{8pt}1(1),2(2)\to 2 出队,剩余 [0,1,3,4]

\hspace{8pt}3(1),4(2)\to 4 出队,剩余 [0,1,3]

\hspace{8pt}0(1),1(2)\to 1 出队,剩余 [0,3]

\hspace{8pt}3(1),0(2)\to 0 出队,剩余 [3],输出 3
import java.util.*;
public class Main{
    public static void main(String[] args){
        int n,k,m;
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        k = in.nextInt();
        m = in.nextInt();
        List<Integer> list = new ArrayList<>();
        for(int i=0;i<n;i++)list.add(i);
        while(true){
            if(list.size()==1)break;
            if(k+m-1>list.size()-1){
                int len = list.size();
                list.remove((k+m-1)%list.size());
                k = (k+m-1)%len;
            }else{
                list.remove(k+m-1);
                k = k+m-1;
            }
        }
        System.out.println(list.get(0));
    }
}

发表于 2026-01-27 15:19:47 回复(0)
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        int m = sc.nextInt();
        //存放布尔值表示该索引位置是否有人
        boolean[] arr = new boolean[n];
        for(int i = 0; i < arr.length; i++){
            arr[i] = true;
        }
        //计数表示当前在圈内的人个数
        int pnum = n;
        //从索引为k的位置开始
        int current = k;
        //外循环结束条件圈内人数为1
        while(pnum > 1){
            //表示当前报数
            int count = 0;
            while(count < m){
                //如果当前位置有人,则报数
                if(arr[current]){
                    count++;
                    //报数等于要出队的数
                    if(count == m){
                        arr[current] = false;//出队状态标为false
                        pnum--; //圈内人减一
                        break;
                    }
                }
                //模的意义在于防止越界,实现环形访问
                current = (current + 1)%n;
            }
        }
        for(int i = 0;i < arr.length; i++){
            if(arr[i]){
                System.out.println(i);
            }
        }
    }
}
发表于 2026-01-07 17:54:13 回复(0)
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        int n=in.nextInt(), k=in.nextInt(), m=in.nextInt();
        StringBuffer sb = new StringBuffer();
        for (int i=0; i<n; i++) {
            sb.append(i);
        }
        while (sb.length()!=1) {
            k+=m;
            if (k>sb.length()) {
                k=k%m;
            }
            sb.deleteCharAt(k-1); // 从自己开始数,所以减一
        }
        System.out.println(sb);
    }
}
还是喜欢用StringBuffer
发表于 2025-10-09 10:27:04 回复(0)
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(); // 总人数
        int k = sc.nextInt(); // 起始编号
        int m = sc.nextInt(); // 报数上限

        // f(n, m) 从 0 开始
        int res = 0;
        for (int i = 2; i <= n; i++) {
            res = (res + m) % i;
        }

        // 平移到从 k 开始
        int ans = (res + k) % n;
        System.out.println(ans);
    }
}

发表于 2025-09-14 16:22:31 回复(0)
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int n = in.nextInt();
            int k = in.nextInt();
            int m = in.nextInt();
            //0在队,1不在
            int[] p =new int[n];
            int init=k;
            int count=0;
            int sum=n;
            while(n!=1){
                if(init>=sum){
                    init=0;
                    continue;
                }
                if(p[init]==1){
                    init++;
                    continue;                  
                }
                     count++;
                if(count==m){
                    p[init]=1;//出局
                    count=0;
                    n--;//人数少一个
                }
                 init++;
            }
           for(int i=0;i<sum;i++){
            if(p[i]==0){
                System.out.print(i)
;            }
           }
        }
    }
}
发表于 2025-07-31 14:13:08 回复(0)