#E. Cow Art(bfs经典习题)

该文描述了一个编程问题,涉及计算由人类和红绿色盲的奶牛观察的彩色方格图案中不同区域的数量。通过两次使用广度优先搜索(BFS)算法,分别计算人和奶牛看到的连通块,其中奶牛将红色和绿色视为同一种颜色。问题提供了一种解决方案,包括输入处理、两次BFS实现及边界条件判断。

题目

说明

一个有关奶牛的鲜为人知的事实是她们都是红绿色盲,也就是说,在她们看来,红色和绿色是一样的(译者注:奶牛把这种颜色称作“红绿色”)。这使得我们设计的艺术作品难以同时符合人类和奶牛的审美口味。考虑一个由N x N格字符表示的方形绘画作品,其中每个字符为R(红),G(绿)或者B(蓝)。一幅绘画如果有许多互不相同的着色“区域”,则我们认为它是有趣的。如果两个字符是直接相邻的(一个在另一个的东、南、西、北方向)且其表示的颜色相同,则这两个字符属于同一个区域。例如,下面这幅绘画作品:

RRRBB

GGBBB

BBBRR

BBRRR

RRRRR

如果由人类来看有4个区域(2个红色,1个蓝色和1个绿色区域),而如果由奶牛来看则只有3个区域(2个红绿色,1个蓝色区域)。现给你一副绘画作为输入,请计算该作品由人类和奶牛来看分别有多少个区域。

输入格式

第1行:整数N(N<=100)。

第2..1+N行:每行包含一个长度为N的字符串,表示绘画作品的一行。

输出格式

第1行:两个空格隔开的整数,分别给出由人类和奶牛欣赏绘画作品时会看见多少个区域。

样例

输入数据 1

### 迷宫最短路径算法的实现 在C++中,使用广度优先搜索(BFS)是解决迷宫最短路径问题的常用方法。以下是一个适合初学者的实现方式,仅使用 `<iostream>` 头文件,并避免复杂的数据结构[^1]。 #### 算法思想 广度优先搜索(BFS)是一种逐层扩展节点的搜索策略,适用于寻找从起点到终点的最短路径。通过维护一个队列来存储待访问的节点,确保每次扩展的节点都是当前层的所有节点,从而保证找到的路径是最短的。 #### 实现代码 以下是基于 BFS 的迷宫最短路径算法的实现: ```cpp #include <iostream> using namespace std; // 定义迷宫大小 const int MAX = 100; int maze[MAX][MAX]; // 迷宫数组 bool visited[MAX][MAX]; // 访问标记数组 int dist[MAX][MAX]; // 距离数组 // 方向数组,表示四个可能的移动方向 int dx[4] = {1, -1, 0, 0}; int dy[4] = {0, 0, 1, -1}; // 判断是否可以移动到某个位置 bool isValid(int x, int y, int n, int m) { return (x >= 0 && x < n && y >= 0 && y < m && !visited[x][y] && maze[x][y] == 0); } // BFS函数 void bfs(int startX, int startY, int endX, int endY, int n, int m) { // 初始化队列 struct Node { int x, y; }; Node nodes[MAX * MAX]; int front = 0, rear = 0; // 起点入队 nodes[rear].x = startX; nodes[rear].y = startY; rear++; visited[startX][startY] = true; dist[startX][startY] = 0; // 开始BFS while (front < rear) { Node current = nodes[front++]; if (current.x == endX && current.y == endY) { break; // 找到终点 } for (int i = 0; i < 4; i++) { int newX = current.x + dx[i]; int newY = current.y + dy[i]; if (isValid(newX, newY, n, m)) { nodes[rear].x = newX; nodes[rear].y = newY; rear++; visited[newX][newY] = true; dist[newX][newY] = dist[current.x][current.y] + 1; } } } } int main() { int n, m; // 迷宫的行数和列数 cin >> n >> m; // 输入迷宫 for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> maze[i][j]; visited[i][j] = false; dist[i][j] = -1; // 初始化距离为-1 } } int startX, startY, endX, endY; // 起点和终点坐标 cin >> startX >> startY >> endX >> endY; // 调用BFS bfs(startX, startY, endX, endY, n, m); // 输出结果 if (dist[endX][endY] != -1) { cout << "最短路径步数: " << dist[endX][endY] << endl; } else { cout << "无法到达终点" << endl; } return 0; } ``` #### 代码说明 1. **迷宫表示**:使用二维数组 `maze` 表示迷宫,`0` 表示可通过的路径,`1` 表示障碍物。 2. **访问标记**:使用 `visited` 数组记录每个位置是否已被访问。 3. **距离数组**:`dist` 数组记录从起点到每个位置的最短距离。 4. **方向数组**:`dx` 和 `dy` 定义了四个可能的移动方向(上下左右)。 5. **队列实现**:由于未使用 STL 的 `queue`,手动实现了队列操作。 #### 注意事项 - 确保输入的迷宫数据合法,且起点和终点坐标有效。 - 如果迷宫中存在无法到达终点的情况,程序会输出“无法到达终点”。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值