这个用java怎么写啊,写出c给我参考一下也行,没思路

假设有一个人围成一圈,按顺序每人分配一个编号一到n,后续活动中,每个人分配的编号始终不变,现在从编号为1的人开始按编号从小到大的顺序,从1开始报号,报号规则为123……。报到M的人出列剩下的人仍组成一圈,然后从下一个人开始又从1开始报号报道M的人出列以此类推,直到所有人出列,输出依次出列的人编号序列。


import java.util.ArrayList;
import java.util.List;

public class Josephus {
    public static List<Integer> josephus(int n, int m) {
        List<Integer> result = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        for (int i = 1; i <= n; i++) {
            list.add(i);
        }
        int index = 0;
        while (list.size() > 0) {
            index = (index + m - 1) % list.size();
            result.add(list.remove(index));
        }
        return result;
    }

    public static void main(String[] args) {
        List<Integer> result = josephus(10, 3);
        for (Integer i : result) {
            System.out.print(i + " ");
        }
    }
}

使用两个 List,一个用来保存所有人的编号,一个用来保存出列的人的编号。使用一个循环来模拟报号的过程,每次将 index 加上 m-1,并使用取模操作使得 index 在 0 到 list.size()-1 之间循环。找到当前要出列的人后,将其从 list 中移除,并将其编号添加到 result 中。重复这个过程,直到 list 中的所有人都出列。最后输出 result,即为出列顺序的编号序列。

可以用数组存储n个序号,然后每次将第m个序号移出,即将其设置为-1,然后如此循环,直到每个序号都被移出就可以了。

import java.util.Scanner;

public class IdGameTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Scanner sc = new Scanner(System.in);
        // 获取n的序号
        System.out.print("请输入最大序号n:");
        int n = sc.nextInt();
        if (n<1) {
            System.out.println("序号必须大于1");
            return ;
        }
        
        // 获取m的编号
        System.out.print("请输入m的编号:");
        int m = sc.nextInt();
        if (m<1) {
            System.out.println("m的编号必须大于1");
            return ;
        }
        
        int Ids[] = new int[n];
        // 把从1到n的每个序号存入数组
        for(int i=0;i<n;i++) {
            Ids[i] = i+1;
        }
        
        int out=0;  // 已经出列的人数
        int start=0;  // 当前报数到的序号
        while(out<n) {  // 如果出列的人数小于n,则一直循环
            
            // 遍历数组,完成出列 
            for(int i=0;i<n;i++) {
                if(Ids[i]!=-1) {  // 如果当前元素的不为-1,即仍在列,则报数一次
                    start++;                
                }
                
                if(start==m) {  // 如果报数到m,则将当前序号输出,并将此序号出列
                    System.out.print(Ids[i]+" ");  // 输出当前序号
                    Ids[i]=-1;  // 出列
                    start=0; // start赋值为0,表示重新开始报数
                    out++;  // 出列人数+1
                }
            }
            //System.out.println("out="+out);
        }
        
        //System.out.println("out="+out);
        
    }

}

img

下面是一种Java实现,使用了循环链表来模拟人围成一圈,按照报号规则依次出列的过程。

import java.util.ArrayList;

public class JosephusProblem {
    public static void main(String[] args) {
        int n = 10; // 人数
        int m = 3;  // 报号规则
        ArrayList<Integer> list = new ArrayList<Integer>();
        for (int i = 1; i <= n; i++) {
            list.add(i);
        }
        int index = 0;
        while (list.size() > 0) {
            index = (index + m - 1) % list.size();
            System.out.print(list.remove(index) + " ");
        }
    }
}

这个实现中,首先将所有人的编号放入一个ArrayList中。然后使用一个循环,每次取出第M个人,将其从ArrayList中移除,并输出其编号。直到ArrayList为空,所有人都出列了。

其中,变量index用于记录当前要报号的人的位置,每次取出第M个人时,使用取余运算保证了报号规则的循环性。

这只是一个简单的实现,如果需要处理更复杂的问题,可能需要使用更高效的数据结构和算法。