一个BFS,虽然洛谷难度标签是提高,但是感觉还行。
很熟悉的传送门,比较特殊的地方是需要剪枝(可能是因为我题目刷少了,还没遇到过BFS剪枝
AC代码:
/*
* @Author: hesorchen
* @Date: 2020-04-14 10:33:26
* @LastEditTime: 2020-06-24 23:36:50
* @Link: https://hesorchen.github.io/
*/
#include <map>
#include <set>
#include <list>
#include <queue>
#include <deque>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define endl '\n'
#define PI acos(-1)
#define PB push_back
#define ll long long
#define INF 0x3f3f3f3f
#define mod 3123456777
#define pll pair<ll, ll>
#define lowbit(abcd) (abcd & (-abcd))
#define max(a, b) ((a > b) ? (a) : (b))
#define min(a, b) ((a < b) ? (a) : (b))
#define IOS \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0);
#define FRE \
{ \
freopen("in.txt", "r", stdin); \
freopen("out.txt", "w", stdout); \
}
inline ll read()
{
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
//==============================================================================
bool vis[310][310];
bool vis2[310][310];
char mp[310][310];
ll mov[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
struct node
{
ll x, y, step;
};
queue<node> q;
ll sx, sy, ex, ey;
vector<pll> vec[30];
ll ans = INF;
ll n, m;
void bfs()
{
while (q.size())
{
node temp = q.front();
q.pop();
if (temp.x == ex && temp.y == ey)
{
ans = min(ans, temp.step);
continue;
}
if (temp.step > ans) //剪枝 没减tle四个点
continue;
for (int i = 0; i < 4; i++)
{
ll xx = temp.x + mov[i][0];
ll yy = temp.y + mov[i][1];
if (xx >= 1 && yy >= 1 && xx <= n && yy <= m && !vis[xx][yy] && mp[xx][yy] != '#' && vis2[xx][yy] <= 1)
{
if (mp[xx][yy] == '.' || mp[xx][yy] == '=')
{
vis[xx][yy] = 1;
q.push(node{xx, yy, temp.step + 1});
}
else if (mp[xx][yy] <= 'Z' && mp[xx][yy] >= 'A')
{
ll x1 = vec[mp[xx][yy] - 'A'][0].first;
ll y1 = vec[mp[xx][yy] - 'A'][0].second;
ll x2 = vec[mp[xx][yy] - 'A'][1].first;
ll y2 = vec[mp[xx][yy] - 'A'][1].second;
vis2[x1][y1]++;
vis2[x2][y2]++;
if (x1 == xx && y1 == yy)
q.push(node{x2, y2, temp.step + 1});
else if (x2 == xx && y2 == yy)
q.push(node{x1, y1, temp.step + 1});
}
}
}
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> mp[i] + 1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
if (mp[i][j] == '=')
ex = i, ey = j;
if (mp[i][j] == '@')
sx = i, sy = j;
if (mp[i][j] <= 'Z' && mp[i][j] >= 'A')
vec[mp[i][j] - 'A'].PB(make_pair(i, j));
}
vis[sx][sy] = 1;
q.push(node{sx, sy, 0});
bfs();
cout << (ans == INF ? -1 : ans) << endl;
return 0;
}