• 填充颜色游戏


    无语死了这题。

    题目描述

    小明最近迷上下面一款游戏。游戏开始时, 系统将随机生成一个 N × N  的  正方形棋盘, 棋盘的每个格子都由六种颜色中的一种绘制。在每个步骤中, 玩家选择一种颜色, 并将与左上角连接的所有网格更改为该特定颜色。“两  个网格是连接的”这一说法意味着这两个网格之间存在一条路径,条件是  该路径上的相邻网格具有相同的颜色并共享一条边。通过这种方式,玩家  可以从起始网格(左上角) 给棋盘涂色, 直至所有网格都是相同的颜色。下  图显示了 4×4 游戏的前两个步骤(颜色标记为 0 到 5):

    解题思路

    1. 这个问题的核心是使用BFS来模拟棋盘上的颜色填充过程。
    2. 初始时,我们从左上角的颜色开始,并逐步改变与左上角相连接的区域的颜色。
    3. 为了优化算法,我们首先检查了两个特定情况:是否只有两种颜色1和2,并分别处理它们,因为单一的算法对这种特殊情况总比实际步数多1。
    4. 如果没有符合特定情况,我们开始执行BFS逻辑,直到整个棋盘被填满为止。
    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. using namespace std;
    7. const int dx[] = { 1, -1, 0, 0 };
    8. const int dy[] = { 0, 0, 1, -1 };
    9. bool is_valid(int x, int y, int n) {
    10. return 0 <= x && x < n && 0 <= y && y < n;
    11. }
    12. int bfs(vectorint>>& board, int n) {
    13. // 检查特定情况1和2
    14. int count1 = 0, count2 = 0;
    15. for (int i = 0; i < n; ++i)
    16. for (int j = 0; j < n; ++j) {
    17. if (board[i][j] == 1) count1++;
    18. if (board[i][j] == 2) count2++;
    19. }
    20. if (count1 + count2 == n * n) {
    21. if (count2 < count1) return 1;
    22. if (count1 == count2) return 2;
    23. }
    24. setint>>> visited;
    25. queueint, int, vectorint>>>> q;
    26. q.push({ board[0][0], 0, board });
    27. while (!q.empty()) {
    28. int color, steps;
    29. vectorint>> cur_board;
    30. tie(color, steps, cur_board) = q.front();
    31. q.pop();
    32. bool all_same = true;
    33. for (int i = 0; i < n && all_same; ++i)
    34. for (int j = 0; j < n && all_same; ++j)
    35. if (cur_board[i][j] != color) all_same = false;
    36. if (all_same) return steps;
    37. for (int new_color = 0; new_color < 6; ++new_color) {
    38. if (new_color == color) continue;
    39. vectorint>> new_board = cur_board;
    40. vectorint, int>> stack = { {0, 0} };
    41. while (!stack.empty()) {
    42. int x, y;
    43. tie(x, y) = stack.back();
    44. stack.pop_back();
    45. for (int i = 0; i < 4; ++i) {
    46. int nx = x + dx[i], ny = y + dy[i];
    47. if (is_valid(nx, ny, n) && new_board[nx][ny] == color) {
    48. new_board[nx][ny] = new_color;
    49. stack.push_back({ nx, ny });
    50. }
    51. }
    52. }
    53. if (visited.find(new_board) == visited.end()) {
    54. visited.insert(new_board);
    55. q.push({ new_color, steps + 1, new_board });
    56. }
    57. }
    58. }
    59. return -1;
    60. }
    61. int main() {
    62. int n;
    63. cin >> n;
    64. vectorint>> board(n, vector<int>(n));
    65. for (int i = 0; i < n; ++i)
    66. for (int j = 0; j < n; ++j)
    67. cin >> board[i][j];
    68. cout << bfs(board, n) << endl;
    69. return 0;
    70. }

     

  • 相关阅读:
    Wireshark详细使用教程
    动态规划专项---最长上升子序列模型
    VSCODE解决git合并过程中的冲突问题;error: failed to push some refs to
    使用 Apache SkyWalking 进行 Spring Cloud 应用的分布式追踪与监控:完整教程
    使用Docker伪分布式安装hadoop
    【uni-app + uView】CountryCodePicker 国家区号组件
    java毕业设计疫情防控管理系统Mybatis+系统+数据库+调试部署
    中介模式简介
    亚马逊小类目排名怎么看?亚马逊小类目是什么意思?——站斧浏览器
    SP1557 GSS2 - Can you answer these queries II【线段树】
  • 原文地址:https://blog.csdn.net/LYXlyxll/article/details/133898227