QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#116402 | #2359. The Five Bishops | ckiseki | TL | 0ms | 0kb | C++20 | 5.2kb | 2023-06-28 19:34:54 | 2023-06-28 19:34:57 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
using P = pair<int, int>;
int parity(int x) {
return (x % 2 + 2) % 2;
}
vector<pair<P, P>> calc(array<P, 5> ori, array<P, 5> tar, P king) {
array<int, 5> ord;
iota(ord.begin(), ord.end(), 0);
do {
// cout << "ord =";
// for (auto x : ord) cout << ' ' << x;
// cout << '\n';
constexpr int dx[] = {0, 0, 1, 1, 1, -1, -1, -1};
constexpr int dy[] = {1, -1, 0, 1, -1, 0, 1, -1};
array<bool, 5> dead = {};
auto solve = [&](auto self, int i, P k) -> bool {
if (i == 5) {
vector<int> c[2];
for (int j = 0; j < 5; ++j) if (not dead[j])
c[parity(tar[ord[j]].first + tar[ord[j]].second)].push_back(ord[j]);
if (c[0].size() < 2 or c[1].size() < 2)
return false;
return true;
}
if (not dead[i]) {
auto [x, y] = ori[ord[i]];
auto [nx, ny] = tar[ord[i]];
if (x + y == nx + ny) {
for (int j = 0; j < i; ++j) {
auto [xj, yj] = tar[ord[j]];
if (xj + yj != x + y)
continue;
if (x <= xj and xj <= nx)
return false;
if (nx <= xj and xj <= x)
return false;
}
for (int j = i + 1; j < 5; ++j) {
auto [xj, yj] = ori[ord[j]];
if (xj + yj != x + y)
continue;
if (x <= xj and xj <= nx)
return false;
if (nx <= xj and xj <= x)
return false;
}
} else if (x - y == nx - ny) {
for (int j = 0; j < i; ++j) {
auto [xj, yj] = tar[ord[j]];
if (xj - yj != x - y)
continue;
if (x <= xj and xj <= nx)
return false;
if (nx <= xj and xj <= x)
return false;
}
for (int j = i + 1; j < 5; ++j) {
auto [xj, yj] = ori[ord[j]];
if (xj - yj != x - y)
continue;
if (x <= xj and xj <= nx)
return false;
if (nx <= xj and xj <= x)
return false;
}
} else assert(false);
}
for (int o = 0; o < 8; o++) {
auto pre = dead;
P nk = {k.first + dx[o], k.second + dy[o]};
for (int j = i + 1; j < 5; ++j) {
if (ori[ord[j]] == nk)
dead[j] = true;
}
if (not self(self, i + 1, nk)) return false;
dead = pre;
}
return true;
};
vector<pair<P, P>> r;
if (solve(solve, 0, king)) {
for (int j = 0; j < 5; ++j)
r.emplace_back(ori[ord[j]], tar[ord[j]]);
return r;
}
} while (next_permutation(ord.begin(), ord.end()));
return {};
}
void solve() {
mt19937 rnd(7122);
uniform_int_distribution<int> rng(-100'000'000, 100'000'000), binary(0, 1);
array<P, 5> b;
P king;
for (auto &[x, y] : b)
scanf("%d%d", &x, &y);
scanf("%d%d", &king.first, &king.second);
auto move_to = [&](int x1, int y1, int x2, int y2) {
printf("%d %d %d %d\n", x1, y1, x2, y2);
fflush(stdout);
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
if (x1 == 0 and y1 == 0 and x2 == 0 and y2 == 0)
return true;
king = {x2, y2};
return false;
};
vector<pair<P, P>> path;
for (int trial = 0; trial < 5; ++trial) {
array<P, 5> ps;
for (int i = 0; i < 5; ++i) {
auto [x, y] = b[i];
int v = rng(rnd), o = binary(rnd);
if (o) {
ps[i] = {v, (x + y) - v};
} else {
ps[i] = {v, y + v - x};
}
}
path = calc(b, ps, king);
if (not path.empty()) break;
}
if (path.empty()) {
puts("0 0 0 0");
return;
}
vector<P> tmp;
array<bool, 5> dead = {};
for (int i = 0; i < 5; ++i) {
if (dead[i]) continue;
auto [p1, p2] = path[i];
if (move_to(p1.first, p1.second, p2.first, p2.second))
return;
tmp.push_back(p2);
for (int j = i + 1; j < 5; ++j)
if (king == path[j].first)
dead[j] = true;
}
vector<P> ps[2];
for (auto [x, y] : tmp)
ps[parity(x + y)].emplace_back(x, y);
vector<P> cur;
const int o = king.first + king.second;
int v[2][2] = {{o-10, o+10}, {o-11, o+11}};
for (int i : {0, 1}) {
for (int j : {0, 1}) {
auto [x, y] = ps[i][j];
int d = (v[i][j] - (x + y)) / 2;
if (move_to(x, y, x + d, y + d))
return;
cur.emplace_back(x + d, y + d);
}
}
sort(cur.begin(), cur.end(), [](P lhs, P rhs) {
return lhs.first + lhs.second < rhs.first + rhs.second;
});
assert (cur[1].first + cur[1].second < king.first + king.second);
assert (king.first + king.second < cur[2].first + cur[2].second);
while (true) {
if (cur[0].first + cur[0].second + 2 != king.first + king.second) {
if (move_to(cur[0].first, cur[0].second, cur[0].first + 1, cur[0].second + 1)) {
return;
}
++cur[0].first, ++cur[0].second;
swap(cur[0], cur[1]);
continue;
}
if (cur[3].first + cur[3].second - 2 != king.first + king.second) {
if (move_to(cur[3].first, cur[3].second, cur[3].first - 1, cur[3].second - 1)) {
return;
}
--cur[3].first, --cur[3].second;
swap(cur[3], cur[2]);
continue;
}
break;
}
int x1 = king.first, y1 = king.second + 2;
if (move_to(cur[3].first, cur[3].second, x1, y1)) {
return;
}
cur[3] = {x1, y1};
int x2 = king.first, y2 = king.second - 2;
if (move_to(cur[0].first, cur[0].second, x2, y2)) {
return;
}
cur[0] = {x2, y2};
int x3 = king.first, y3 = king.second - 2;
assert(move_to(cur[0].first, cur[0].second, x3, y3));
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
solve();
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Time Limit Exceeded
input:
4 1 1 2 2 3 3 4 4 5 5 7 5