题目描述
马是象棋(包括中国象棋和国际象棋)中的棋子,走法是每步直一格再斜一格,即先横着或者直者走一格,然后再斜着走一个对角线,可进可退,可越过河界,俗称"马走日"字。
给定 m 行 n 列的棋盘(网格图),棋盘上只有棋子象棋中的棋子“马”,并且每个棋子有等级之分,等级为 k 的马可以跳 1~k 步(走的方式与象棋中“马”的规则一样,不可以超出棋盘位置),问是否能将所有马跳到同一位置,如果存在,输出最少需要的总步数(每匹马的步数相加),不存在则输出-1。
注:允许不同的马在跳的过程中跳到同一位置,坐标为(x,y)的马跳一次可以跳到的坐标为:(x+1, y+2),(x+1, y-2),(x+2, y+1),(x+2, y-1),(x-1, y+2),(x-1, y-2),(x-2, y+1),(x-2, y-1),的格点上,但是不可以超出棋盘范围。
输入描述
第一行输入m,n,代表 m 行 n 列的网格图棋盘(1 ≤ m, n ≤ 25)
接下来输入 m 行 n 列的网格图棋盘,如果第 i 行,第 j 列的元素为 "." ,代表此格点没有棋子,如果为数字 k(1 ≤ k ≤ 9),代表此格点存在等级为 k 的“马”
输出描述
输出最少需要的总步数(每匹马的步数相加),不存在则输出-1。
用例1
输入
3 2
..
2.
..
输出
0
说明
只有一匹马,不需要跳动
用例2
输入
3 5
47.48
4744.
7....
输出
17
#include <bits/stdc++.h>
using namespace std;
// #define endl '\n'
#define int long long
#define fastio \
ios_base::sync_with_stdio(false); \
cin.tie(NULL); \
cout.tie(NULL);
#pragma GCC optimize(3)
typedef pair<int, int> pii;
const double pi = acos(-1);
const int M = 2e5 + 10;
const int mod = 1e9 + 7;
const int inf = 1e9 + 5;
const int INF = (1ll << 32);
const int dx[] = {1, 1, 2, 2, -1, -1, -2, -2};
const int dy[] = {2, -2, 1, -1, 2, -2, 1, -1};
int m, n;
bool check(int x, int y)
{
return x >= 0 && x < m && y >= 0 && y < n;
}
vector<vector<int>> bfs(int startx, int starty, int k)
{
vector<vector<int>> dist(m, vector<int>(n, INT_MAX));
dist[startx][starty] = 0;
queue<pair<int, int>> q;
q.push({startx, starty});
while (q.size())
{
int x = q.front().first;
int y = q.front().second;
q.pop();
for (int i = 0; i < 8; i++)
{
int nx = x + dx[i];
int ny = y + dy[i];
if (check(nx, ny) && dist[nx][ny] == INT_MAX)
{
dist[nx][ny] = dist[x][y] + 1;
q.push({nx, ny});
}
}
}
return dist;
}
void solve()
{
cin >> m >> n;
vector<vector<int>> board(m, vector<int>(n, 0));
vector<pair<int, int>> horses; // 存储每个马的位置
vector<int> horseLevels; // 存储每个马的等级
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
char c;
cin >> c;
if (c != '.')
{
int level = c - '0';
horses.push_back({i, j});
horseLevels.push_back(level);
board[i][j] = level;
}
}
}
// 获取所有可能的目标位置
int minTotalSteps = INT_MAX;
// 对每个目标位置进行尝试
for (int targetX = 0; targetX < m; targetX++)
{
for (int targetY = 0; targetY < n; targetY++)
{
int totalSteps = 0;
bool possible = true;
// 对每匹马进行 BFS,计算从马的当前位置到目标位置的步数
for (int i = 0; i < horses.size(); i++)
{
int startX = horses[i].first;
int startY = horses[i].second;
int k = horseLevels[i];
vector<vector<int>> dist = bfs(startX, startY, k);
// 如果目标位置不可达
if (dist[targetX][targetY] == INT_MAX)
{
possible = false;
break;
}
totalSteps += dist[targetX][targetY];
}
if (possible)
{
minTotalSteps = min(minTotalSteps, totalSteps);
}
}
}
if (minTotalSteps == INT_MAX)
{
cout << -1 << endl;
}
else
{
cout << minTotalSteps << endl;
}
return;
}
signed main()
{
fastio int T = 1;
// cin >> T;
// cout<<fixed<<setprecision(10);
while (T--)
{
solve();
}
return 0;
}