Javaで順列（階乗通り・n!通りの列挙・全探索）

n!通りを列挙したいときに、
Javaではc++でいうnext_permutationのようなものがないので
自作する必要があります。

#### 実装

```java:
import java.util.Arrays;

public class Main {
    private static void permutation(int[] seed) {
        int[] perm = new int[seed.length];
        boolean[] used = new boolean[seed.length];
        buildPerm(seed, perm, used, 0);
    }

    private static void buildPerm(int[] seed, int[] perm, boolean[] used, int index) {
        if (index == seed.length) {
            procPerm(perm);
            return;
        }

        for (int i = 0; i < seed.length; i++) {
            if (used[i])
                continue;
            perm[index] = seed[i];
            used[i] = true;
            buildPerm(seed, perm, used, index + 1);
            used[i] = false;
        }
    }

    private static void procPerm(int[] perm) {
        System.out.println(Arrays.toString(perm));
    }

    public static void main(String[] args) throws Exception {
        permutation(new int[] { 1, 2, 3 });
    }
}

```

#### 実行結果
```
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
```

# 例題
[ABC183C](https://atcoder.jp/contests/abc183/tasks/abc183_c)

#### 実装例
```Java:
import java.util.Scanner;
import java.util.stream.IntStream;

public class Main {

    private static long t[][];
    private static int n;
    private static int k;
    private static int ans = 0;

    private static void permutation(int[] seed) {
        int[] perm = new int[seed.length];
        boolean[] used = new boolean[seed.length];
        buildPerm(seed, perm, used, 0);
    }

    private static void buildPerm(int[] seed, int[] perm, boolean[] used, int index) {
        if (index == seed.length) {
            procPerm(perm);
            return;
        }

        for (int i = 0; i < seed.length; i++) {
            if (used[i]) {
                continue;
            }
            perm[index] = seed[i];
            used[i] = true;
            buildPerm(seed, perm, used, index + 1);
            used[i] = false;
        }
    }

    private static void procPerm(int[] perm) {
        // System.out.println(Arrays.toString(perm));

        // 都市1から出発
        int start = 0;

        // 経路の移動時間の合計
        long sum = 0;

        // 都市1から出発してすべての都市を経由する経路の合計の計算
        for (int i = 0; i < perm.length; i++) {
            sum += t[start][perm[i]];
            start = perm[i];
        }

        // 最後の都市から都市1に戻る経路を合計
        sum += t[start][0];

        // 移動時間=kの場合ans++
        if (sum == k) {
            ans++;
        }
    }

    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);

        n = sc.nextInt();
        k = sc.nextInt();
        t = new long[n][n];

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                t[i][j] = sc.nextLong();
            }
        }

        // すべての都市をちょうど1度ずつ訪問する順列を生成
        // ex) 4都市の場合(開始終了は都市1固定のため除く)
        // [2, 3, 4], [2, 4, 3]
        // [3, 2, 4], [3, 4, 2]
        // [4, 2, 3], [4, 3, 2]
        permutation(IntStream.range(1, n).toArray());

        System.out.println(ans);

        sc.close();
    }
}
```


# 参考
https://maku77.github.io/java/numstr/permutation.html