QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#116402#2359. The Five BishopsckisekiTL 0ms0kbC++205.2kb2023-06-28 19:34:542023-06-28 19:34:57

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-06-28 19:34:57]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2023-06-28 19:34:54]
  • 提交

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

output:


result: