社区讨论

目前的交互库

P14667[ICPC 2025 Seoul R] Adventurer Dabi参与者 59已保存回复 59

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
59 条
当前快照
1 份
快照标识符
@mizjec79
此快照首次捕获于
2025/12/10 12:56
2 个月前
此快照最后确认于
2025/12/12 21:45
2 个月前
查看原帖
因为没有代码测对不对,所以就放在这里了。大体上是官方的交互库改了适配格式兼容洛谷的要求。
CPP
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#include <string>
#include <map>
#include "testlib.h"
using namespace std;
typedef pair<int, int> pii;

int main(int argc, char *argv[]) {
	registerTestlibCmd(argc, argv);

	// read input
	const auto read_int = [&]() -> int {
		int r = inf.readInt();
		return r;
	};
	const int h = read_int();
	const int w = read_int();
	inf.readLine();
	vector<string> A(h);
	for (auto &S : A) {
		S = inf.readLine();
		if (int(S.size()) != w) {
			quitf(_fail, "Judge error: Invalid map length.");
			// exit(1);
		}
	}

	// find {key, treasure, tabi}
	int key_y = -1, key_x = -1;
	int treasure_y = -1, treasure_x = -1;
	int tabi_y = -1, tabi_x = -1;
	for (int i = 0; i < h; i++) for (int j = 0; j < w; j++) {
		if ('k' == A[i][j]) {
			// key
			key_y = i; key_x = j;
			A[i][j] = '.';
		} else if ('t' == A[i][j]) {
			// treasure
			treasure_y = i; treasure_x = j;
			A[i][j] = '.';
		} else if ('v' == A[i][j]) {
			// tabi
			tabi_y = i; tabi_x = j;
			A[i][j] = '.';
		}
	}

	// make teleports
	map<char, vector<pii>> tels;
	for (int i = 0; i < h; i++) for (int j = 0; j < w; j++) {
		if ('A' <= A[i][j] && A[i][j] <= 'Z') {
			tels[A[i][j]].emplace_back(i, j);
		}
	}

	for (const auto &[name, V] : tels) {
		if (!('A' <= name && name <= 'F')) {
			quitf(_fail, "Judge error: Invalid teleport name.");
			// exit(1);
		}
		if (2 != int(V.size())) {
			quitf(_fail, "Judge error: Invalid teleport pairing.");
			// exit(1);
		}
	}

	const auto checkMove = [&](int y, int x, const int dy, const int dx) -> bool {
		y += dy; x += dx;
		return 0 <= y && y < h && 0 <= x && x < w && '#' != A[y][x];
	};
 
	const auto computeMove = [&](int y, int x, const int dy, const int dx) -> pii {
		// move one step
		y += dy; x += dx;
 
		// check teleport
		if (0 <= y && y < h && 0 <= x && x < w && 'A' <= A[y][x] && A[y][x] <= 'Z') {
			const auto &V = tels[A[y][x]];
 
			// take teleport
			y ^= V[0].first ^ V[1].first;
			x ^= V[0].second ^ V[1].second;
 
			// move one more step
			y += dy; x += dx;
		}
 
		return pii(y, x);
	};

	// compute minimum length "key -> treasure"
	const int ans_len = [&]() -> int {
		// BFS from key
		vector<vector<int>> D(h, vector<int>(w, -1));
		vector<pii> V;
		D[key_y][key_x] = 0;
		V.emplace_back(key_y, key_x);
		for (int vi = 0; vi < int(V.size()); vi++) {
			const auto [y, x] = V[vi];
			const int d = D[y][x] + 1;
			for (const auto [dy, dx] : {pii(1, 0), pii(-1, 0), pii(0, 1), pii(0, -1)}) {
				if (checkMove(y, x, dy, dx)) {
					const auto [ny, nx] = computeMove(y, x, dy, dx);
					if (D[ny][nx] < 0) {
						D[ny][nx] = d;
						V.emplace_back(ny, nx);
					}
				}
			}
		}
		return D[treasure_y][treasure_x];
	}();
	if (ans_len <= 0) {
		quitf(_fail, "PANIC: fail to compute shortest path.");
		// exit(1);
	}

	bool flag_pick = false;
 
	const auto printTabiInfo = [&]() -> void {
		string S = "000000";
 
		// north, south, east, west
		const pii dirs[4] = {pii(-1, 0), pii(1, 0), pii(0, 1), pii(0, -1)};
		for (int i = 0; i < 4; i++) {
			if ('#' == A[tabi_y + dirs[i].first][tabi_x + dirs[i].second]) {
				S[i] = '1';
			}
		}
 
		// unpicked key
		if (tabi_y == key_y && tabi_x == key_x && !flag_pick) {
			S[4] = '1';
		}
 
		// treasure
		if (tabi_y == treasure_y && tabi_x == treasure_x) {
			S[5] = '1';
		}
 
		cout << S << endl;
	};

	int lft_cmds = 230'611;
	int num_tot_cmds = 0, num_runs = 0;
 
	const map<char, pair<string, pii>> dir_cmds = [&]() -> map<char, pair<string, pii>> {
		map<char, pair<string, pii>> ret;
		ret['N'] = {"north", pii(-1, 0)};
		ret['S'] = {"south", pii(1, 0)};
		ret['E'] = {"east", pii(0, 1)};
		ret['W'] = {"west", pii(0, -1)};
		return ret;
	}();

	while (true) {
		if (lft_cmds <= 0) {
			cout << "wrong" << endl;
			quitf(_wa, "Too many commands.");
			return 0;
		}
 
		if (flag_pick && ans_len <= num_runs) {
			cout << "wrong" << endl;
			quitf(_wa, "Not shortest.");
			return 0;
		}
 
		printTabiInfo();
 
		lft_cmds -= 1;
		num_tot_cmds += 1;
		if (flag_pick) {
			num_runs += 1;
		}
 
		string S;
		cin >> S;
		if (1 != int(S.size())) {
			cout << "wrong" << endl;
			quitf(_wa, "Malformed command.");
			return 0;
		}
 
		const char cmd = S[0];
		if ('N' == cmd || 'S' == cmd || 'E' == cmd || 'W' == cmd) {
			// move
			auto it = dir_cmds.find(cmd);
			if (dir_cmds.end() == it) {
				quitf(_fail, "PANIC: fail to parse move command.");
				// exit(1);
			}
			const auto [name, d] = it->second;
			if (checkMove(tabi_y, tabi_x, d.first, d.second)) {
				tie(tabi_y, tabi_x) = computeMove(tabi_y, tabi_x, d.first, d.second);
			} else {
				cout << "wrong" << endl;
				quitf(_wa, "Invalid move command.");
				return 0;
			}
 
			if (flag_pick && tabi_y == treasure_y && tabi_x == treasure_x) {
				// found the treasure chest!
				break;
			}
		} else if ('K' == cmd) {
			// pick up the key
			if (!flag_pick && tabi_y == key_y && tabi_x == key_x) {
				flag_pick = true;
			} else {
				cout << "wrong" << endl;
				quitf(_wa, "Invalid pick command.");
				return 0;
			}
		} else {
			cout << "wrong" << endl;
			quitf(_wa, "Malformed command.");
			return 0;
		}
	}

	if (ans_len != num_runs) {
		quitf(_fail, "Contestant found the better route.");
		// exit(1);
	}
 
	cout << "correct" << endl;
	quitf(_ok, "Correct with %d queries; %d moves.", num_tot_cmds, num_runs);
	return 0;
}

回复

59 条回复,欢迎继续交流。

正在加载回复...