結果

問題 No.3047 Verification of Sorting Network
ユーザー 👑 Mizar
提出日時 2025-01-16 11:14:55
言語 JavaScript
(node v23.5.0)
結果
AC  
実行時間 1,024 ms / 2,000 ms
コード長 4,762 bytes
コンパイル時間 466 ms
コンパイル使用メモリ 9,252 KB
実行使用メモリ 60,824 KB
最終ジャッジ日時 2025-03-05 20:32:06
合計ジャッジ時間 48,574 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 61
権限があれば一括ダウンロードができます

ソースコード

diff #

const MaxT = 10000;
const MaxN = 27;
const MaxCost = 1e8;
var Ok = function (data) {
  return { tag: "Yes", data: data };
};
var Err = function (data) {
  return { tag: "No", data: data };
};
function isSortingNetwork(n, cmps) {
  const state_zero = 0;
  const state_one = 1;
  const state_unknown = 2;
  // initial state: all elements are unknown
  var stack = [[0, Array(n).fill(state_unknown), 0, n - 1]];
  var unused = Array(cmps.length).fill(true);
  var unsorted = Array(n - 1).fill(false);
  var m = cmps.length;
  // branch loop
  a: while (stack.length > 0) {
    // get branch state
    // i: index of cmps
    // p: state of each element
    // z: leading index of non-zero elements
    // o: trailing index of non-one elements
    var [i, p, z, o] = stack.pop();
    // CEs (compare/exchange elements) loop
    while (i < m) {
      // get next comparison
      var [a, b] = cmps[i++];
      if (p[a] === state_zero || p[b] === state_one) {
        // (0, 0) or (1, 1) or (0, 1) or (0, ?) or (?, 1), no operation, continue to next CE
      } else if (p[a] === state_unknown && p[b] === state_unknown) {
        unused[i - 1] = false;
        // both elements are unknown
        // branch into (0, 0) and (?, 1)
        // copy state for (0, 0) new branch
        // set state for (?, 1) current branch
        var q = p.slice();
        q[a] = state_zero;
        q[b] = state_zero;
        p[b] = state_one;
        // find 'q' leading non-zero element
        for (var j = z; j < o; ++j) {
          if (q[j] !== state_zero) {
            // if not sorted, push branch into stack
            stack.push([i, q, j, o]);
            break;
          }
        }
        // find p trailing non-one element if p is not sorted
        while (p[o] === state_one) {
          --o;
          // if p is '0...01...1' or '0...0?1...1',
          if (z === o) {
            // p is sorted, continue to next branch
            continue a;
          }
        }
      } else {
        unused[i - 1] = false;
        // if (1, 0) or (?, 0) or (1, ?), swap elements
        [p[a], p[b]] = [p[b], p[a]];
        // find p leading non-zero element if p is not sorted
        while (p[z] === state_zero) {
          ++z;
          // if p is '0...01...1' or '0...0?1...1',
          if (z === o) {
            // p is sorted, continue to next branch
            continue a;
          }
        }
        // find p trailing non-one element if p is not sorted
        while (p[o] === state_one) {
          --o;
          // if p is '0...01...1' or '0...0?1...1',
          if (z === o) {
            // p is sorted, continue to next branch
            continue a;
          }
        }
      }
    }
    // if p is not sorted
    for (var j = 0; j < n - 1; ++j) {
      if (p[j] !== state_zero && p[j + 1] !== state_one) {
        unsorted[j] = true;
      }
    }
  }
  if (
    unsorted.some(function (x) {
      return x;
    })
  ) {
    return Err(unsorted);
  }
  // if p is sorted for all branches
  return Ok(unused);
}
function main() {
  var input = require("fs").readFileSync("/dev/stdin", "utf8").split("\n");
  var index = 0;
  var t = parseInt(input[index++], 10);
  if (t > MaxT) throw new Error("t must be <= ".concat(MaxT));
  // phi = (1 + sqrt(5)) / 2 : golden ratio
  var phi = Math.sqrt(1.25) + 0.5;
  // testcases cost <= 1e8
  var cost = 0.0;
  for (var i = 0; i < t; ++i) {
    var [n, m] = input[index++].split(" ").map(function (str) {
      return parseInt(str, 10);
    });
    if (!(2 <= n && n <= MaxN && 1 <= m && m <= (n * (n - 1)) / 2))
      throw new Error("Invalid n or m");
    cost += m * Math.pow(phi, n);
    if (cost > MaxCost) throw new Error("Cost must be <= ".concat(MaxCost));

    // 1-indexed to 0-indexed
    var va = input[index++].split(" ").map((str) => parseInt(str, 10) - 1);
    var vb = input[index++].split(" ").map((str) => parseInt(str, 10) - 1);
    var cmps = va.map((a, i) => [a, vb[i]]);
    if (cmps.length !== m) throw new Error("Invalid cmps length");
    if (cmps.some(([a, b]) => !(0 <= a && a < b && b < n))) throw new Error("Invalid a or b");

    var { data, tag } = isSortingNetwork(n, cmps);
    console.log(tag);
    if (tag === "Yes") {
      if (data.length !== m) throw new Error("Invalid data length");
      console.log(data.filter((x) => x).length);
      console.log(
        data
          .map((x, i) => (x ? i + 1 : 0))
          .filter((x) => x)
          .join(" ")
      );
    } else if (tag === "No") {
      if (data.length !== n - 1) throw new Error("Invalid data length");
      console.log(data.filter((x) => x).length);
      console.log(
        data
          .map((x, i) => (x ? i + 1 : 0))
          .filter((x) => x)
          .join(" ")
      );
    }
  }
}
main();
0