约瑟夫环

来源:互联网 发布:ubuntu重命名文件夹 编辑:程序博客网 时间:2024/04/30 15:03

题目描述:略

递归方式:

设有(1,2,3,……,k-1,k,k+1,……,n)n个数,当k出列时,那么有
k+1 -->1
k+2 -->2
...
n -->n-k
1 -->n-k+1
...
k-1 -->n-1
由上面一组式子可以推出,若知道新产生的n-1个数中某个数x,那么很显然可以推出x在原数列里的位置,即x‘=(x+k)%n,

比如说:有数1,2,3,4,5,6,7,8  八个数,数到4出列,

这样,第一次出列后按顺序剩下5,6,7,8,1,2,3   这时1在第5个位置,可以得知它原来在第(5+4)%9 = 1 个位置,

由此,我们可以得到一个递推公式
f[1]=1
f[n]=(f[n-1]+k)%n (n>1)
上面的递推公式中,在某种情况下,f[n-1]+k会整除n,如n=2,k=3,这时我们修要对上式进行修正:
f[n]=(f[n-1]+k)%n;if(f[n]==0)f[n]=n;()

public class ExeDemo65 {public static void main(String[] args) {int n = 0, k = 0;Scanner sc = new Scanner(System.in);n = sc.nextInt();k = sc.nextInt();System.out.println(jos(n, k));}public static int jos(int n, int k) {int x;if (n == 1)x = 1;else {x = (jos(n - 1, k) + k) % n;if (x == 0)x = n;}return x;}}


非递归方式:

运用ArrayList类采用动态数组方式,使得问题简易方便。

public class ExeDemo65 {public static void main(String[] args) {ArrayList<String> al = new ArrayList<String>();Scanner sc = new Scanner(System.in);int n = sc.nextInt();int m = sc.nextInt();int search = 0;for (int i = 1; i <= n; i++) {al.add(i + " ");}while (al.size() > 0) {search += (m - 1);search %= al.size();System.out.print(al.remove(search));}}}



原创粉丝点击