当前位置: 首页 > news >正文

ZCS的随机游走的题解

题目链接

我们看到这道题,一下子就可以想到用模拟来做,但是!地图存不下去,这是一个严重的问题。

怎么办呢?

方法一:

我们可以用不同的数字来代替字符,再用short存。

CODE:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main() {
    // 读取输入
    int n, m, x;
    cin >> n >> m >> x;

    // 读取网格
    vector<vector<short>> grid(n, vector<short>(m));
    int start_i = 0, start_j = 0; // 初始位置
    for (int i = 0; i < n; ++i) {
        string row;
        cin >> row;
        for (int j = 0; j < m; ++j) {
            if (row[j] == '#') {
                start_i = i;
                start_j = j;
                grid[i][j] = 0; // 起点视为空地
            } else if (row[j] == 'X') {
                grid[i][j] = 1; // 1 表示障碍物
            } else {
                grid[i][j] = 0; // 0 表示空地
            }
        }
    }

    // 读取移动方向
    vector<short> opts(x);
    for (int i = 0; i < x; ++i) {
        cin >> opts[i];
    }

    // 模拟游走
    int current_i = start_i, current_j = start_j; // 当前位置
    for (int i = 0; i < x; ++i) {
        int opt = opts[i];
        int next_i = current_i, next_j = current_j;

        // 计算下一步的坐标
        if (opt == 1) {
            next_i--; // 上
        } else if (opt == 2) {
            next_i++; // 下
        } else if (opt == 3) {
            next_j--; // 左
        } else if (opt == 4) {
            next_j++; // 右
        }

        // 检查是否越界或撞到障碍物
        if (next_i < 0 || next_i >= n || next_j < 0 || next_j >= m || grid[next_i][next_j] == 1) {
            cout << "ZCS is die!" << endl;
            return 0;
        }

        // 更新当前位置
        current_i = next_i;
        current_j = next_j;
    }

    // 输出最终坐标
    cout << current_i - start_i << " " << current_j - start_j << endl;

    return 0;
}

方法二:

我们把障碍用vector存下来。

CODE:

#include <iostream>
using namespace std;

// 定义方向偏移量,分别对应上、下、左、右
const int dx[] = {-1, 1, 0, 0};
const int dy[] = {0, 0, -1, 1};

int main() {
    short n, m, x;
    // 读取教室的长、宽和步数
    cin >> n >> m >> x;
    short startX, startY;
    char cell;

    // 读取地图并确定起点坐标
    for (short i = 0; i < n; ++i) {
        for (short j = 0; j < m; ++j) {
            cin >> cell;
            if (cell == '#') {
                startX = j;
                startY = i;
            }
        }
    }

    short currentX = startX;
    short currentY = startY;

    for (short i = 0; i < x; ++i) {
        short opt;
        cin >> opt;
        // 方向选项减 1 以匹配偏移量数组的索引
        opt--;

        short newX = currentX + dx[opt];
        short newY = currentY + dy[opt];

        // 动态检查新位置是否越界或者遇到障碍
        bool isInvalid = false;
        if (newX < 0 || newX >= m || newY < 0 || newY >= n) {
            isInvalid = true;
        } else {
            // 重新读取地图中对应位置的信息
            short pos = newY * m + newX;
            short currentRow = 0;
            cin.clear();
            cin.seekg(0, ios::beg);
            for (short k = 0; k < n; ++k) {
                for (short l = 0; l < m; ++l) {
                    cin >> cell;
                    if (k * m + l == pos) {
                        if (cell == 'X') {
                            isInvalid = true;
                        }
                        break;
                    }
                }
                if (isInvalid) {
                    break;
                }
            }
        }

        if (isInvalid) {
            cout << "ZCS is die!" << endl;
            return 0;
        }
        currentX = newX;
        currentY = newY;
    }

    // 如果没有撞到障碍,输出最终坐标
    cout << "(" << currentX - startX << ", " << currentY - startY << ")" << endl;
    return 0;
}    

注:有可能过不了。 

方法三:

我们可以把经历过的坐标记录下来,用hash去重,并且看是否与某个障碍物的坐标重合了。

CODE:

#include <iostream>
#include <vector>
#include <string>
#include <unordered_set>

using namespace std;

// 定义一个哈希函数用于存储坐标
struct CoordinateHash {
    size_t operator()(const pair<int, int>& p) const {
        return static_cast<size_t>(p.first) * 100000 + p.second;
    }
};

int main() {
    // 读取输入
    int n, m, x;
    cin >> n >> m >> x;

    // 读取网格
    vector<string> grid(n);
    int start_i = 0, start_j = 0; // 初始位置
    for (int i = 0; i < n; ++i) {
        cin >> grid[i];
        for (int j = 0; j < m; ++j) {
            if (grid[i][j] == '#') {
                start_i = i;
                start_j = j;
            }
        }
    }

    // 读取移动方向
    vector<int> opts(x);
    for (int i = 0; i < x; ++i) {
        cin >> opts[i];
    }

    // 记录障碍物的坐标
    unordered_set<pair<int, int>, CoordinateHash> obstacles;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (grid[i][j] == 'X') {
                obstacles.insert({i - start_i, j - start_j});
            }
        }
    }

    // 模拟游走
    int current_i = 0, current_j = 0; // 当前位置(相对于起点)
    unordered_set<pair<int, int>, CoordinateHash> visited; // 记录走过的坐标
    visited.insert({current_i, current_j});

    for (int i = 0; i < x; ++i) {
        int opt = opts[i];
        int next_i = current_i, next_j = current_j;

        // 计算下一步的坐标
        if (opt == 1) {
            next_i--; // 上
        } else if (opt == 2) {
            next_i++; // 下
        } else if (opt == 3) {
            next_j--; // 左
        } else if (opt == 4) {
            next_j++; // 右
        }

        // 检查是否撞到障碍物
        if (obstacles.find({next_i, next_j}) != obstacles.end()) {
            cout << "ZCS is die!" << endl;
            return 0;
        }

        // 检查是否越界
        if (next_i < -start_i || next_i >= n - start_i || next_j < -start_j || next_j >= m - start_j) {
            cout << "ZCS is die!" << endl;
            return 0;
        }

        // 更新当前位置
        current_i = next_i;
        current_j = next_j;
        visited.insert({current_i, current_j});
    }

    // 输出最终坐标
    cout << current_i << " " << current_j << endl;

    return 0;
}

多么简单的一道题。

相关文章:

  • 用Llama 3微调私有知识库:本地部署避坑指南
  • 大屏技术汇集【目录】
  • CMake 函数和宏
  • 34-三数之和
  • 应用案例 | 核能工业:M-PM助力核工业科研项目
  • 华为网路设备学习-16 虚拟路由器冗余协议(VRRP)
  • vue设置自定义logo跟标题
  • 基于ISO 26262的汽车芯片认证流程解读
  • 使用PlotNeuralNet绘制ResNet50模型
  • 第十五次CCF-CSP认证(含C++源码)
  • VC6.0图文安装教程
  • NFT在艺术品市场的影响:面纵花魄还是一场夢?
  • 【读点论文】Chain Replication for Supporting High Throughput and Availability
  • PLY格式文件如何转换成3DTiles格式——使用GISBox软件实现高效转换
  • 【NPU 系列专栏 3.0 -- scale-out 和 scale-in 和 scale-up 和 scale-down
  • Vue学习汇总(JS长期更新版)
  • 【leetcode hot 100 22】括号生成
  • 算法2--两数相加
  • 【nnUnetv2】Code分析
  • C++算法代码-植物生长算法求解多目标车辆路径规划问题
  • 图集|俄罗斯举行纪念苏联伟大卫国战争胜利80周年阅兵式
  • 图忆|红场阅兵:俄罗斯30年来的卫国战争胜利日阅兵式
  • 涨知识|没想到吧,体育老师强调的运动恢复方法是错的?
  • 青年与人工智能共未来,上海创新创业青年50人论坛徐汇分论坛举办
  • 悬疑推理联合书单|虫神山事件
  • 国家矿山安全监察局发布《煤矿瓦斯防治能力评估办法》