import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; import java.util.Collections; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; class BilliardsBall { // 1~MAX_BALL_NUMBERの数が書かれた球を使う static final int MAX_BALL_NUMBER = 15; { for(int i = 3; i <= 7; i++) new BilliardsBall(i).print(); } private int n; private int m; private ArrayList<int[]> result = new ArrayList<int[]>(); private long time; BilliardsBall(int n) { this.n = n; forEach(true, n, p -> { bit.clear(); int sum = 0; for (int i = 0; i < p.length; i++) { sum += p[i]; } if (sum < m) return; bit.set(sum); for (int i = 0; i < p.length; i++) { sum = 0; for (int j = 0; j < p.length - 1; j++) { sum += p[(i + j) % p.length]; bit.set(sum); } } int max = bit.nextClearBit(1) - 1; if (m <= max) { if (m < max) result.clear(); int[] is = new int[p.length]; for(int i = 0; i < p.length - 1; i++) { is[i] = p[i + 1]; } is[p.length - 1] = p[0]; result.add(is); m = max; } }); int compare = 0; for (int i = 0; i < n && compare == 0; i++) { } return compare; }); time = TimeUnit.NANOSECONDS.toMillis(e - s); } public void print() { for(int[] is : result) { } } /** * 順列を生成してConsumerに処理を投げる * @param reduce 計算量削減させるかどうか * @param num 球の数 * @param c */ static void forEach(boolean reduce, int num, Consumer<int[]> c) { // 計算量削減のために最初3個をA,B,Cとした場合 B=1, C<Aとなるようにする。(基点の位置確定と反転の回避) if (reduce) { int[] perm = new int[num]; boolean[] used = new boolean[MAX_BALL_NUMBER + 1]; perm[1] = 1; used[1] = true; for (int i = 2; i <= MAX_BALL_NUMBER - 1; i++) { perm[2] = i; used[i] = true; for (int j = i + 1; j <= MAX_BALL_NUMBER; j++) { perm[0] = j; used[j] = true; p(perm, used, 3, c); used[j] = false; } used[i] = false; } } else // 計算量削減せずに全パターン調べる { p(new int[num], new boolean[MAX_BALL_NUMBER + 1], 0, c); } } /** * 再帰で順列生成 */ private static void p(int[] perm, boolean[] used, int p, Consumer<int[]> c) { if (perm.length == p) { c.accept(perm); return; } for (int i = 1; i <= MAX_BALL_NUMBER; i++) { if (used[i]) continue; used[i] = true; perm[p] = i; p(perm, used, p + 1, c); used[i] = false; } } }
Standard input is empty
N=3, M=7, Time=83ms [1, 2, 4] N=4, M=13, Time=4ms [1, 2, 6, 4] [1, 3, 2, 7] N=5, M=21, Time=11ms [1, 3, 10, 2, 5] N=6, M=31, Time=127ms [1, 2, 5, 4, 6, 13] [1, 2, 7, 4, 12, 5] [1, 3, 2, 7, 8, 10] [1, 3, 6, 2, 5, 14] [1, 7, 3, 2, 4, 14] N=7, M=39, Time=1582ms [1, 2, 8, 6, 13, 5, 4] [1, 3, 14, 6, 5, 2, 8] [1, 4, 2, 7, 3, 8, 14] [1, 4, 3, 9, 2, 15, 5] [1, 6, 2, 3, 13, 4, 10] [1, 9, 3, 5, 2, 4, 15]