Submission #69571774
Source Code Expand
#include <bits/stdc++.h>
using namespace std;
int N, t_i, t_j;
vector<vector<char>> grid;
set<pair<int, int>> revealed;
set<pair<int, int>> placed_treants;
int entrance_i, entrance_j;
int turn_count = 0;
int di[4] = {-1, 1, 0, 0};
int dj[4] = {0, 0, -1, 1};
// 预计算距离矩阵
vector<vector<int>> dist_from_entrance;
vector<vector<int>> dist_from_flower;
// 快速BFS计算距离
void bfs_distance(int si, int sj, vector<vector<int>>& dist, const vector<vector<char>>& map) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
dist[i][j] = INT_MAX;
}
}
queue<pair<int, int>> q;
q.push(make_pair(si, sj));
dist[si][sj] = 0;
while (!q.empty()) {
int i = q.front().first;
int j = q.front().second;
q.pop();
for (int d = 0; d < 4; d++) {
int ni = i + di[d], nj = j + dj[d];
if (ni >= 0 && ni < N && nj >= 0 && nj < N &&
dist[ni][nj] == INT_MAX && map[ni][nj] == '.') {
dist[ni][nj] = dist[i][j] + 1;
q.push(make_pair(ni, nj));
}
}
}
}
// 快速连通性检查 - 只检查是否可达,不计算路径
bool is_connected_fast(int si, int sj, int ei, int ej, const vector<vector<char>>& map) {
if (map[si][sj] == 'T' || map[ei][ej] == 'T') return false;
vector<vector<bool>> visited(N, vector<bool>(N, false));
queue<pair<int, int>> q;
q.push(make_pair(si, sj));
visited[si][sj] = true;
while (!q.empty()) {
int i = q.front().first;
int j = q.front().second;
q.pop();
if (i == ei && j == ej) return true;
for (int d = 0; d < 4; d++) {
int ni = i + di[d], nj = j + dj[d];
if (ni >= 0 && ni < N && nj >= 0 && nj < N &&
!visited[ni][nj] && map[ni][nj] == '.') {
visited[ni][nj] = true;
q.push(make_pair(ni, nj));
}
}
}
return false;
}
// 获取最短路径(简化版,只找一条路径)
vector<pair<int, int>> get_shortest_path_fast(int si, int sj, int ei, int ej, const vector<vector<char>>& map) {
if (map[si][sj] == 'T' || map[ei][ej] == 'T') return {};
vector<vector<pair<int, int>>> prev(N, vector<pair<int, int>>(N, make_pair(-1, -1)));
vector<vector<bool>> visited(N, vector<bool>(N, false));
queue<pair<int, int>> q;
q.push(make_pair(si, sj));
visited[si][sj] = true;
while (!q.empty()) {
int i = q.front().first;
int j = q.front().second;
q.pop();
if (i == ei && j == ej) {
vector<pair<int, int>> path;
int cur_i = i, cur_j = j;
while (cur_i != si || cur_j != sj) {
path.push_back(make_pair(cur_i, cur_j));
pair<int, int> p = prev[cur_i][cur_j];
cur_i = p.first;
cur_j = p.second;
}
path.push_back(make_pair(si, sj));
reverse(path.begin(), path.end());
return path;
}
// 优先选择更接近目标的方向
vector<int> dir_priority = {0, 1, 2, 3};
if (ei > i) swap(dir_priority[0], dir_priority[1]); // 优先向下
if (ej > j) swap(dir_priority[2], dir_priority[3]); // 优先向右
for (int d_idx = 0; d_idx < 4; d_idx++) {
int d = dir_priority[d_idx];
int ni = i + di[d], nj = j + dj[d];
if (ni >= 0 && ni < N && nj >= 0 && nj < N &&
!visited[ni][nj] && map[ni][nj] == '.') {
visited[ni][nj] = true;
prev[ni][nj] = make_pair(i, j);
q.push(make_pair(ni, nj));
}
}
}
return {};
}
// 快速评估位置价值
int evaluate_position_fast(int i, int j, int p_i, int p_j, bool flower_revealed) {
int score = 0;
// 1. 距离花朵的远近
int flower_dist = abs(i - t_i) + abs(j - t_j);
score += max(0, 15 - flower_dist);
// 2. 如果花朵已揭示,优先阻塞路径
if (flower_revealed) {
// 简单评估:如果这个位置在冒险者和花朵之间
if ((i >= min(p_i, t_i) && i <= max(p_i, t_i)) &&
(j >= min(p_j, t_j) && j <= max(p_j, t_j))) {
score += 20;
}
} else {
// 3. 如果花朵未揭示,在花朵周围形成保护
if (flower_dist <= 3) {
score += 25;
}
// 4. 在冒险者和花朵之间的位置
int mid_i = (p_i + t_i) / 2;
int mid_j = (p_j + t_j) / 2;
if (abs(i - mid_i) + abs(j - mid_j) <= 2) {
score += 15;
}
}
// 5. 创建死胡同的潜力
int revealed_neighbors = 0;
for (int d = 0; d < 4; d++) {
int ni = i + di[d], nj = j + dj[d];
if (ni >= 0 && ni < N && nj >= 0 && nj < N) {
if (revealed.find(make_pair(ni, nj)) != revealed.end()) {
revealed_neighbors++;
}
}
}
// 如果周围有已揭示的单元格,这个位置更有价值
score += revealed_neighbors * 3;
return score;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
// 读取输入
cin >> N >> t_i >> t_j;
grid.resize(N, vector<char>(N));
for (int i = 0; i < N; i++) {
string s;
cin >> s;
for (int j = 0; j < N; j++) {
grid[i][j] = s[j];
}
}
entrance_i = 0;
entrance_j = N / 2;
revealed.insert(make_pair(entrance_i, entrance_j));
// 初始化距离矩阵
dist_from_entrance.resize(N, vector<int>(N, INT_MAX));
dist_from_flower.resize(N, vector<int>(N, INT_MAX));
// 预计算距离
bfs_distance(entrance_i, entrance_j, dist_from_entrance, grid);
bfs_distance(t_i, t_j, dist_from_flower, grid);
// 主循环
while (true) {
turn_count++;
int p_i, p_j;
cin >> p_i >> p_j;
int n;
cin >> n;
vector<pair<int, int>> new_revealed;
for (int i = 0; i < n; i++) {
int x, y;
cin >> x >> y;
revealed.insert(make_pair(x, y));
new_revealed.push_back(make_pair(x, y));
}
// 检查是否到达花朵
if (p_i == t_i && p_j == t_j) {
break;
}
// 构建真实地图
vector<vector<char>> real_map = grid;
for (auto& pos : placed_treants) {
real_map[pos.first][pos.second] = 'T';
}
// 构建试探地图
vector<vector<char>> tentative_map(N, vector<char>(N, '.'));
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (revealed.find(make_pair(i, j)) != revealed.end()) {
tentative_map[i][j] = real_map[i][j];
}
}
}
// 获取可放置位置(限制数量)
vector<pair<int, int>> available_positions;
int max_positions = 100; // 限制评估的位置数量
// 优先考虑关键区域的位置
bool flower_revealed = revealed.find(make_pair(t_i, t_j)) != revealed.end();
// 区域1: 花朵周围
for (int i = max(0, t_i-3); i <= min(N-1, t_i+3) && available_positions.size() < max_positions; i++) {
for (int j = max(0, t_j-3); j <= min(N-1, t_j+3); j++) {
if (revealed.find(make_pair(i, j)) == revealed.end() &&
real_map[i][j] == '.') {
available_positions.push_back(make_pair(i, j));
if (available_positions.size() >= max_positions) break;
}
}
}
// 区域2: 冒险者和花朵之间
if (available_positions.size() < max_positions) {
int mid_i = (p_i + t_i) / 2;
int mid_j = (p_j + t_j) / 2;
for (int i = max(0, mid_i-2); i <= min(N-1, mid_i+2) && available_positions.size() < max_positions; i++) {
for (int j = max(0, mid_j-2); j <= min(N-1, mid_j+2); j++) {
if (revealed.find(make_pair(i, j)) == revealed.end() &&
real_map[i][j] == '.' &&
find(available_positions.begin(), available_positions.end(), make_pair(i, j)) == available_positions.end()) {
available_positions.push_back(make_pair(i, j));
if (available_positions.size() >= max_positions) break;
}
}
}
}
// 区域3: 随机补充
if (available_positions.size() < max_positions / 2) {
// 如果关键区域位置太少,随机补充一些
for (int i = 0; i < N && available_positions.size() < max_positions; i++) {
for (int j = 0; j < N && available_positions.size() < max_positions; j++) {
if (revealed.find(make_pair(i, j)) == revealed.end() &&
real_map[i][j] == '.' &&
find(available_positions.begin(), available_positions.end(), make_pair(i, j)) == available_positions.end()) {
available_positions.push_back(make_pair(i, j));
}
}
}
}
if (available_positions.empty()) {
cout << 0 << endl;
continue;
}
// 快速选择最佳位置
pair<int, int> best_pos = make_pair(-1, -1);
int best_score = -1;
// 限制评估的数量
int max_evaluate = min(30, (int)available_positions.size());
// 第一阶段:快速筛选
vector<pair<int, pair<int, int>>> candidates;
for (int idx = 0; idx < max_evaluate; idx++) {
int i = available_positions[idx].first;
int j = available_positions[idx].second;
// 快速连通性检查
vector<vector<char>> test_map = real_map;
test_map[i][j] = 'T';
if (!is_connected_fast(entrance_i, entrance_j, t_i, t_j, test_map)) {
continue;
}
int score = evaluate_position_fast(i, j, p_i, p_j, flower_revealed);
// 如果是花朵已揭示阶段,检查是否在路径上
if (flower_revealed) {
auto path = get_shortest_path_fast(p_i, p_j, t_i, t_j, tentative_map);
for (const auto& pos : path) {
if (pos.first == i && pos.second == j) {
score += 30;
break;
}
}
}
candidates.push_back(make_pair(score, make_pair(i, j)));
}
// 第二阶段:精细评估(只对前几名候选)
if (!candidates.empty()) {
sort(candidates.begin(), candidates.end(), greater<pair<int, pair<int, int>>>());
// 只评估前3名候选的路径影响
int top_n = min(3, (int)candidates.size());
for (int i = 0; i < top_n; i++) {
int score = candidates[i].first;
int pos_i = candidates[i].second.first;
int pos_j = candidates[i].second.second;
// 计算路径长度影响
if (flower_revealed) {
int original_length = get_shortest_path_fast(p_i, p_j, t_i, t_j, tentative_map).size();
if (original_length > 0) {
vector<vector<char>> test_tentative = tentative_map;
test_tentative[pos_i][pos_j] = 'T';
int new_length = get_shortest_path_fast(p_i, p_j, t_i, t_j, test_tentative).size();
if (new_length > 0) {
score += (new_length - original_length) * 2;
}
}
}
if (score > best_score) {
best_score = score;
best_pos = candidates[i].second;
}
}
}
// 输出结果
if (best_pos.first != -1) {
placed_treants.insert(best_pos);
cout << 1 << " " << best_pos.first << " " << best_pos.second << endl;
} else {
// 尝试找到一个安全位置
bool found = false;
for (const auto& pos : available_positions) {
vector<vector<char>> test_map = real_map;
test_map[pos.first][pos.second] = 'T';
if (is_connected_fast(entrance_i, entrance_j, t_i, t_j, test_map)) {
placed_treants.insert(pos);
cout << 1 << " " << pos.first << " " << pos.second << endl;
found = true;
break;
}
}
if (!found) {
cout << 0 << endl;
}
}
// 防止超时
if (turn_count > 2000) {
cout << -1 << endl;
break;
}
}
return 0;
}
Submission Info
| Submission Time |
|
| Task |
A - Treant's Forest |
| User |
a_computers_xh |
| Language |
C++ 23 (gcc 12.2) |
| Score |
18786 |
| Code Size |
13777 Byte |
| Status |
AC |
| Exec Time |
288 ms |
| Memory |
3704 KiB |
Compile Error
Main.cpp: In function ‘int main()’:
Main.cpp:240:88: warning: comparison of integer expressions of different signedness: ‘std::vector<std::pair<int, int> >::size_type’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
240 | for (int i = max(0, t_i-3); i <= min(N-1, t_i+3) && available_positions.size() < max_positions; i++) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
Main.cpp:245:52: warning: comparison of integer expressions of different signedness: ‘std::vector<std::pair<int, int> >::size_type’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
245 | if (available_positions.size() >= max_positions) break;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
Main.cpp:251:40: warning: comparison of integer expressions of different signedness: ‘std::vector<std::pair<int, int> >::size_type’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
251 | if (available_positions.size() < max_positions) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
Main.cpp:254:96: warning: comparison of integer expressions of different signedness: ‘std::vector<std::pair<int, int> >::size_type’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
254 | for (int i = max(0, mid_i-2); i <= min(N-1, mid_i+2) && available_positions.size() < max_positions; i++) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
Main.cpp:260:56: warning: comparison of integer expressions of different signedness: ‘std::vector<std::pair<int, int> >::size_type’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
260 | if (available_positions.size() >= max_positions) break;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
Main.cpp:267:40: warning: comparison of integer expressions of different signedness: ‘std::vector<std::pair<int, int> >::size_type’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
267 | if (available_positions.size() < max_positions / 2) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
Main.cpp:269:65: warning: comparison of integer expressions of different signedness: ‘std::vector<std::pair<int, int> >::size_type’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
269 | for (int i = 0; i < N && available_positions.size() < max_positions; i++) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
Main.cpp:270:69: warning: comparison of integer expressions of different signedness: ‘std::vector<std::pair<int, int> >::size_type’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
270 | for (int j = 0; j < N && available_positions.size() < max_positions; j++) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
Judge Result
| Set Name |
test_ALL |
| Score / Max Score |
18786 / 100000000000 |
| Status |
|
| Set Name |
Test Cases |
| test_ALL |
test_0000.txt, test_0001.txt, test_0002.txt, test_0003.txt, test_0004.txt, test_0005.txt, test_0006.txt, test_0007.txt, test_0008.txt, test_0009.txt, test_0010.txt, test_0011.txt, test_0012.txt, test_0013.txt, test_0014.txt, test_0015.txt, test_0016.txt, test_0017.txt, test_0018.txt, test_0019.txt, test_0020.txt, test_0021.txt, test_0022.txt, test_0023.txt, test_0024.txt, test_0025.txt, test_0026.txt, test_0027.txt, test_0028.txt, test_0029.txt, test_0030.txt, test_0031.txt, test_0032.txt, test_0033.txt, test_0034.txt, test_0035.txt, test_0036.txt, test_0037.txt, test_0038.txt, test_0039.txt, test_0040.txt, test_0041.txt, test_0042.txt, test_0043.txt, test_0044.txt, test_0045.txt, test_0046.txt, test_0047.txt, test_0048.txt, test_0049.txt, test_0050.txt, test_0051.txt, test_0052.txt, test_0053.txt, test_0054.txt, test_0055.txt, test_0056.txt, test_0057.txt, test_0058.txt, test_0059.txt, test_0060.txt, test_0061.txt, test_0062.txt, test_0063.txt, test_0064.txt, test_0065.txt, test_0066.txt, test_0067.txt, test_0068.txt, test_0069.txt, test_0070.txt, test_0071.txt, test_0072.txt, test_0073.txt, test_0074.txt, test_0075.txt, test_0076.txt, test_0077.txt, test_0078.txt, test_0079.txt, test_0080.txt, test_0081.txt, test_0082.txt, test_0083.txt, test_0084.txt, test_0085.txt, test_0086.txt, test_0087.txt, test_0088.txt, test_0089.txt, test_0090.txt, test_0091.txt, test_0092.txt, test_0093.txt, test_0094.txt, test_0095.txt, test_0096.txt, test_0097.txt, test_0098.txt, test_0099.txt |
| Case Name |
Status |
Exec Time |
Memory |
| test_0000.txt |
AC |
38 ms |
3548 KiB |
| test_0001.txt |
AC |
35 ms |
3496 KiB |
| test_0002.txt |
AC |
12 ms |
3356 KiB |
| test_0003.txt |
AC |
26 ms |
3584 KiB |
| test_0004.txt |
AC |
11 ms |
3584 KiB |
| test_0005.txt |
AC |
88 ms |
3540 KiB |
| test_0006.txt |
AC |
15 ms |
3684 KiB |
| test_0007.txt |
AC |
20 ms |
3532 KiB |
| test_0008.txt |
AC |
138 ms |
3576 KiB |
| test_0009.txt |
AC |
12 ms |
3452 KiB |
| test_0010.txt |
AC |
87 ms |
3516 KiB |
| test_0011.txt |
AC |
61 ms |
3684 KiB |
| test_0012.txt |
AC |
75 ms |
3608 KiB |
| test_0013.txt |
AC |
83 ms |
3496 KiB |
| test_0014.txt |
AC |
42 ms |
3604 KiB |
| test_0015.txt |
AC |
44 ms |
3588 KiB |
| test_0016.txt |
AC |
40 ms |
3560 KiB |
| test_0017.txt |
AC |
184 ms |
3704 KiB |
| test_0018.txt |
AC |
58 ms |
3496 KiB |
| test_0019.txt |
AC |
10 ms |
3400 KiB |
| test_0020.txt |
AC |
56 ms |
3584 KiB |
| test_0021.txt |
AC |
22 ms |
3500 KiB |
| test_0022.txt |
AC |
140 ms |
3544 KiB |
| test_0023.txt |
AC |
35 ms |
3464 KiB |
| test_0024.txt |
AC |
16 ms |
3472 KiB |
| test_0025.txt |
AC |
19 ms |
3436 KiB |
| test_0026.txt |
AC |
135 ms |
3568 KiB |
| test_0027.txt |
AC |
68 ms |
3644 KiB |
| test_0028.txt |
AC |
153 ms |
3560 KiB |
| test_0029.txt |
AC |
27 ms |
3384 KiB |
| test_0030.txt |
AC |
47 ms |
3624 KiB |
| test_0031.txt |
AC |
67 ms |
3572 KiB |
| test_0032.txt |
AC |
47 ms |
3612 KiB |
| test_0033.txt |
AC |
39 ms |
3516 KiB |
| test_0034.txt |
AC |
15 ms |
3528 KiB |
| test_0035.txt |
AC |
201 ms |
3540 KiB |
| test_0036.txt |
AC |
38 ms |
3536 KiB |
| test_0037.txt |
AC |
15 ms |
3584 KiB |
| test_0038.txt |
AC |
93 ms |
3544 KiB |
| test_0039.txt |
AC |
126 ms |
3564 KiB |
| test_0040.txt |
AC |
49 ms |
3452 KiB |
| test_0041.txt |
AC |
16 ms |
3668 KiB |
| test_0042.txt |
AC |
12 ms |
3476 KiB |
| test_0043.txt |
AC |
19 ms |
3512 KiB |
| test_0044.txt |
AC |
53 ms |
3488 KiB |
| test_0045.txt |
AC |
126 ms |
3640 KiB |
| test_0046.txt |
AC |
209 ms |
3548 KiB |
| test_0047.txt |
AC |
68 ms |
3572 KiB |
| test_0048.txt |
AC |
164 ms |
3660 KiB |
| test_0049.txt |
AC |
84 ms |
3540 KiB |
| test_0050.txt |
AC |
6 ms |
3436 KiB |
| test_0051.txt |
AC |
13 ms |
3480 KiB |
| test_0052.txt |
AC |
23 ms |
3552 KiB |
| test_0053.txt |
AC |
24 ms |
3456 KiB |
| test_0054.txt |
AC |
27 ms |
3612 KiB |
| test_0055.txt |
AC |
18 ms |
3388 KiB |
| test_0056.txt |
AC |
16 ms |
3484 KiB |
| test_0057.txt |
AC |
86 ms |
3524 KiB |
| test_0058.txt |
AC |
32 ms |
3456 KiB |
| test_0059.txt |
AC |
57 ms |
3428 KiB |
| test_0060.txt |
AC |
241 ms |
3576 KiB |
| test_0061.txt |
AC |
90 ms |
3620 KiB |
| test_0062.txt |
AC |
57 ms |
3480 KiB |
| test_0063.txt |
AC |
12 ms |
3504 KiB |
| test_0064.txt |
AC |
73 ms |
3512 KiB |
| test_0065.txt |
AC |
66 ms |
3648 KiB |
| test_0066.txt |
AC |
270 ms |
3560 KiB |
| test_0067.txt |
AC |
28 ms |
3524 KiB |
| test_0068.txt |
AC |
114 ms |
3480 KiB |
| test_0069.txt |
AC |
17 ms |
3508 KiB |
| test_0070.txt |
AC |
51 ms |
3504 KiB |
| test_0071.txt |
AC |
67 ms |
3564 KiB |
| test_0072.txt |
AC |
20 ms |
3548 KiB |
| test_0073.txt |
AC |
288 ms |
3576 KiB |
| test_0074.txt |
AC |
78 ms |
3484 KiB |
| test_0075.txt |
AC |
38 ms |
3488 KiB |
| test_0076.txt |
AC |
10 ms |
3584 KiB |
| test_0077.txt |
AC |
9 ms |
3456 KiB |
| test_0078.txt |
AC |
88 ms |
3620 KiB |
| test_0079.txt |
AC |
54 ms |
3416 KiB |
| test_0080.txt |
AC |
8 ms |
3664 KiB |
| test_0081.txt |
AC |
80 ms |
3528 KiB |
| test_0082.txt |
AC |
83 ms |
3604 KiB |
| test_0083.txt |
AC |
38 ms |
3556 KiB |
| test_0084.txt |
AC |
37 ms |
3488 KiB |
| test_0085.txt |
AC |
21 ms |
3484 KiB |
| test_0086.txt |
AC |
68 ms |
3456 KiB |
| test_0087.txt |
AC |
17 ms |
3528 KiB |
| test_0088.txt |
AC |
26 ms |
3480 KiB |
| test_0089.txt |
AC |
10 ms |
3468 KiB |
| test_0090.txt |
AC |
17 ms |
3588 KiB |
| test_0091.txt |
AC |
23 ms |
3600 KiB |
| test_0092.txt |
AC |
49 ms |
3496 KiB |
| test_0093.txt |
AC |
47 ms |
3616 KiB |
| test_0094.txt |
AC |
34 ms |
3408 KiB |
| test_0095.txt |
AC |
189 ms |
3556 KiB |
| test_0096.txt |
AC |
11 ms |
3472 KiB |
| test_0097.txt |
AC |
102 ms |
3612 KiB |
| test_0098.txt |
AC |
41 ms |
3552 KiB |
| test_0099.txt |
AC |
15 ms |
3536 KiB |