#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <climits>
using namespace std;
const int MAXN = 100; // 假设n不会超过100
int grid[MAXN][MAXN];
int visited[MAXN][MAXN][2]; // visited[x][y][0]表示是否访问过(x,y),visited[x][y][1]表示到达(x,y)的最小花费
// 检查坐标是否有效
bool isValid(int x, int y, int n) {
return x >= 0 && x < n && y >= 0 && y < n;
}
// 广度优先搜索
int bfs(int n, int r1, int c1, int r2, int c2) {
queue<pair<int, int>> q;
q.push({r1, c1});
visited[r1][c1][0] = true;
visited[r1][c1][1] = 0;
while (!q.empty()) {
auto front = q.front();
q.pop();
int x = front.first, y = front.second;
// 检查是否到达目的地
if (x == r2 && y == c2) {
return visited[x][y][1];
}
// 探索四个方向
for (int i = 0; i < 4; ++i) {
int dx = (i == 0) ? -1 : (i == 1) ? 1 : 0;
int dy = (i == 2) ? -1 : (i == 3) ? 1 : 0;
int nx = x + dx, ny = y + dy;
if (isValid(nx, ny, n) && !visited[nx][ny][0] && grid[nx][ny] == 0) {
q.push({nx, ny});
visited[nx][ny][0] = true;
visited[nx][ny][1] = visited[x][y][1] + 1; // 计算花费
}
}
// 考虑搭建桥的情况
if (grid[x][y] == 1) {
for (int i = 0; i < 4; ++i) {
int dx = (i == 0) ? -1 : (i == 1) ? 1 : 0;
int dy = (i == 2) ? -1 : (i == 3) ? 1 : 0;
int nx = x + dx, ny = y + dy;
if (isValid(nx, ny, n) && !visited[nx][ny][0] && grid[nx][ny] == 0) {
q.push({nx, ny});
visited[nx][ny][0] = true;
int cost = (x - nx) * (x - nx) + (y - ny) * (y - ny);
visited[nx][ny][1] = visited[x][y][1] + cost; // 计算搭建桥的花费
}
}
}
}
return INT_MAX; // 如果无法到达目的地
}
int main() {
int n, r1, c1, r2, c2;
// 读取输入...
// 初始化grid和visited数组
memset(grid, 0, sizeof(grid));
memset(visited, 0, sizeof(visited));
int result = bfs(n, r1, c1, r2, c2);
if (result == INT_MAX) {
cout << "无法到达目的地" << endl;
} else {
cout << "最小花费为: " << result << endl;
}
return 0;
}
Alice想要站在一个
nn的矩形中,每个格子由0或1组成,0表示陆地,1表示河流。已知Alice站在点
(r1,c1)上,现在他想要到点
(r2,c2)上去。他可以从他所在的位置每次选择一个方向走一格,一共有4种方向(分别是上下左右)。显然在Alice走的过程中,很可能发现要到达目的地,必须要跨过河流,而Alice并不会游泳。幸运的是,他可以搭一座桥(他最多只能搭一座桥)帮助他跨过河流。桥的起点和终点只能够搭在陆地上,假设起点和终点分别为
(x1,y1)和
(x2,y2),他需要花
(x1-x2)(x1-x2)+(y1-y2)*(y1-y2)。
现在请问最少花费多少?当不需要搭桥的时候,花费为0。