import java.util.concurrent.atomic.AtomicInteger;public final class fannkuchredux implements Runnable {private static final int MAX_N = 32;private static final int NCHUNKS = 360;private static final AtomicInteger taskId = new AtomicInteger(0);private static final fannkuchredux instance = new fannkuchredux();private static int CHUNKSZ;private static int NTASKS;private static int N;private static int[] fact;private static int[] maxFlips;private static int[] checkSums;@Overridepublic void run() {var CHUNKSZ = fannkuchredux.CHUNKSZ;var NTASKS = fannkuchredux.NTASKS;var N = fannkuchredux.N;var fact = fannkuchredux.fact;var maxFlips = fannkuchredux.maxFlips;var checkSums = fannkuchredux.checkSums;var p = new int[MAX_N];var pp = new int[MAX_N];var count = new int[MAX_N];for (int task; (task = taskId.getAndIncrement()) < NTASKS; ) {int idxMin = task * CHUNKSZ;int idxMax = Math.min(fact[N], idxMin + CHUNKSZ);for (int i = 0; i < N; i++)p[i] = i;for (int i = N, idx = idxMin; --i > 0; ) {int d = idx / fact[i];count[i] = d;idx = idx % fact[i];System.arraycopy(p, 0, pp, 0, N); // i + 1for (int j = 0; j <= i; j++)p[j] = j + d <= i ? pp[j + d] : pp[j + d - i - 1];}int maxflips = 1;int chksum = 0;var sign = true;for (int i = idxMin; ; sign = !sign) {int first = p[0];if (first != 0) {int flips = 1;if (p[first] != 0) {System.arraycopy(p, 0, pp, 0, N);int p0 = first;do {flips++;for (int lo = 1, hi = p0 - 1; lo < hi; lo++, hi--) {int t = pp[lo];pp[lo] = pp[hi];pp[hi] = t;}int t = pp[p0];pp[p0] = p0;p0 = t;} while (pp[p0] != 0);}if (maxflips < flips)maxflips = flips;if (sign)chksum += flips;elsechksum -= flips;}if (++i == idxMax)break;// nextPermutationif (sign) {p[0] = p[1];p[1] = first;} else {int t = p[1];p[1] = p[2];p[2] = t;for (int k = 2; ++count[k] > k; k++) {count[k] = 0;for (int j = 0; j <= k; j++)p[j] = p[j + 1];p[k + 1] = first;first = p[0];}}}maxFlips[task] = maxflips;checkSums[task] = chksum;}}static void printResult(int n, int res, int chk) {System.out.println(chk + "\nPfannkuchen(" + n + ") = " + res);}public static void main(String[] args) throws Exception {N = args.length > 0 ? Integer.parseInt(args[0]) : 12;if (N < 0 || N > 12) {printResult(N, -1, -1);return;}if (N <= 1) {printResult(N, 0, 0);return;}//noinspection NonStrictComparisonCanBeEqualityfor (int TEST_COUNT = 1; --TEST_COUNT >= 0; taskId.set(0)) {// var timeBegin = System.nanoTime();fact = new int[N + 1];fact[0] = 1;for (int i = 1; i < fact.length; i++)fact[i] = fact[i - 1] * i;CHUNKSZ = (fact[N] + NCHUNKS - 1) / NCHUNKS;NTASKS = (fact[N] + CHUNKSZ - 1) / CHUNKSZ;System.out.println(NTASKS);maxFlips = new int[NTASKS];checkSums = new int[NTASKS];int nthreads = Runtime.getRuntime().availableProcessors();var threads = new Thread[nthreads];for (int i = 0; i < nthreads; i++)(threads[i] = new Thread(fannkuchredux.instance)).start();for (var t : threads)t.join();int res = 0;for (int v : maxFlips)res = Math.max(res, v);int chk = 0;for (int v : checkSums)chk += v;printResult(N, res, chk);// System.out.println((System.nanoTime() - timeBegin) / 1_000_000 + " ms");}}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。