跳马(多源BFS变种,每个起点有步数限制)
补充几个测试样例
输入
3 2
. .
2 .
. .
输出
0
输入
3 5
4 7 . 4 8
4 7 4 4 .
7 . . . .
输出
17
输入
3 4
. . . .
. 2 . .
. . . .
输出
0
输入
3 4
. . . .
. 2 2 .
. . . .
输出
-1
本题很坑爹的地方在于,输入的字符串还用空格分开,所以读入时不能用读连续字符串的方法,例如
读字符串数组(n * m
字符矩阵,中间无空格)char g[N][N]
写法
for (int i = 0; i < n; i++) scanf("%s", g[i]);//读取
for (int i = 0; i < n; i++) printf("%s\n", g[i]);//输出写法1
for (int i = 0; i < n; i++) puts(g[i]);//输出写法2
只能当成矩阵一个一个读,就和读int型二维矩阵一样。
分析:本题数据量不大且因为每个点有移动步数限制,所以采用每个点都搜一次的方法,搜完一个点,dist数组中存的就是该点到其余所有位置的最小步数,更新到total数组中,如果dist[i][j] == -1
,或dist[i][j] > step
,则说明该点不可达,在total中标记为-1.
最后遍历一遍total数组,把所有-1
改成正无穷,再取最小值输出即可。
C++代码
/**
* Created by Tshaxz on 25-1-16.
*/
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 30, INF = 0x3f3f3f3f;
int n, m;
char g[N][N];
int dist[N][N], total[N][N];
int dx[8] = {1, 2, 2, 1, -1, -2, -2, -1};
int dy[8] = {2, 1, -1, -2, -2, -1, 1, 2};
void bfs(int x, int y, int step)
{
memset(dist, -1, sizeof dist);
queue<PII> q;
dist[x][y] = 0;
q.push({x, y});
while (q.size())
{
auto [x, y] = q.front();
q.pop();
for (int i = 0; i < 8; i++)
{
int a = x + dx[i], b = y + dy[i];
if (a < 0 || a >= n || b < 0 || b >= m) continue;
if (dist[a][b] != -1) continue;
if (dist[a][b] > step) continue;
dist[a][b] = dist[x][y] + 1;
q.push({a, b});
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> m;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> g[i][j];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (g[i][j] != '.')
{
int step = g[i][j] - '0';
bfs(i, j, step);
for (int x = 0; x < n; x++)
for (int y = 0; y < m; y++)
{
if (dist[x][y] > step) total[x][y] = -1;
else if (total[x][y] != -1) total[x][y] += dist[x][y];
}
}
int res = INF;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
if (total[i][j] == -1) total[i][j] = INF;
res = min(res, total[i][j]);
}
if (res == INF) res = -1;
cout << res << '\n';
return 0;
}
debug版代码,可以输出dist与total数组查看
/**
* Created by Tshaxz on 25-1-16.
*/
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 30, INF = 0x3f3f3f3f;
int n, m;
char g[N][N];
int dist[N][N], total[N][N];
int dx[8] = {1, 2, 2, 1, -1, -2, -2, -1};
int dy[8] = {2, 1, -1, -2, -2, -1, 1, 2};
void bfs(int x, int y, int step)
{
memset(dist, -1, sizeof dist);
queue<PII> q;
dist[x][y] = 0;
q.push({x, y});
// printf("step: %d\n", step);
while (q.size())
{
auto [x, y] = q.front();
q.pop();
for (int i = 0; i < 8; i++)
{
int a = x + dx[i], b = y + dy[i];
if (a < 0 || a >= n || b < 0 || b >= m) continue;
if (dist[a][b] != -1) continue;
if (dist[a][b] > step) continue;
dist[a][b] = dist[x][y] + 1;
q.push({a, b});
}
}
}
// void print1()
// {
// printf("dist: \n");
// for (int i = 0; i < n; i++)
// {
// for (int j = 0; j < m; j++) printf("\t%d\t", dist[i][j]);
// puts("");
// }
// }
// void print2()
// {
// printf("total:\n");
// for (int i = 0; i < n; i++)
// {
// for (int j = 0; j < m; j++) printf("\t%d\t", total[i][j]);
// puts("");
// }
// }
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> m;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> g[i][j];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (g[i][j] != '.')
{
int step = g[i][j] - '0';
bfs(i, j, step);
// printf("当前的马:g[%d][%d]:%c\n", i, j, g[i][j]);
// print1();
for (int x = 0; x < n; x++)
for (int y = 0; y < m; y++)
{
if (dist[x][y] > step) total[x][y] = -1;
else if (total[x][y] != -1) total[x][y] += dist[x][y];
}
// print2();
}
int res = INF;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
if (total[i][j] == -1) total[i][j] = INF;
res = min(res, total[i][j]);
}
if (res == INF) res = -1;
cout << res << '\n';
return 0;
}
标签:专题,dist,int,res,BFS,++,step,total,多源
From: https://www.cnblogs.com/Tshaxz/p/18675683