結果
| 問題 |
No.3047 Verification of Sorting Network
|
| ユーザー |
👑 |
| 提出日時 | 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 |
ソースコード
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();