社区讨论
目前的交互库
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 条回复,欢迎继续交流。
正在加载回复...