这题就一 bfs ,没啥好说的
重点:bfs 更新顺序千万不能乱,千万不能乱
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cstdio>
#include<queue>
using namespace std;
const int MAXN = 505;
int n, m, ans;
int dst[MAXN][MAXN], wall[MAXN][MAXN][4];
pair<int, int> s, t;
char mp[MAXN][MAXN];
inline int rd() {
register int x = 0;
register char c = getchar();
register bool f = false;
while(!isdigit(c)) {
f = (c == '-');
c = getchar();
}
while(isdigit(c)) {
x = x * 10 + (c ^ 48);
c = getchar();
}
return f ? -x : x;
}
inline char getc() {
register char c = getchar();
while(c != '.' && c != '#' && !isupper(c)) c = getchar();
return c;
}
inline void bfs() {
memset(dst, 0x3f, sizeof(dst));
queue<pair<int, int> > q;
q.push(s);
dst[s.first][s.second] = 0;
while(!q.empty()) {
pair<int, int> x = q.front(); q.pop();
int curdst = dst[x.first][x.second];
pair<int, int> mindst = make_pair(0x3f3f3f3f, 0);
if(wall[x.first][x.second][0] < mindst.first) {mindst.first = wall[x.first][x.second][0];mindst.second = 0;}
if(wall[x.first][x.second][1] < mindst.first) {mindst.first = wall[x.first][x.second][1];mindst.second = 1;}
if(wall[x.first][x.second][2] < mindst.first) {mindst.first = wall[x.first][x.second][2];mindst.second = 2;}
if(wall[x.first][x.second][3] < mindst.first) {mindst.first = wall[x.first][x.second][3];mindst.second = 3;}
if(dst[x.first - wall[x.first][x.second][0]][x.second] > curdst + mindst.first + 1) {
dst[x.first - wall[x.first][x.second][0]][x.second] = curdst + mindst.first + 1;
q.push(make_pair(x.first - wall[x.first][x.second][0], x.second));
}
if(dst[x.first][x.second + wall[x.first][x.second][1]] > curdst + mindst.first + 1) {
dst[x.first][x.second + wall[x.first][x.second][1]] = curdst + mindst.first + 1;
q.push(make_pair(x.first, x.second + wall[x.first][x.second][1]));
}
if(dst[x.first + wall[x.first][x.second][2]][x.second] > curdst + mindst.first + 1) {
dst[x.first + wall[x.first][x.second][2]][x.second] = curdst + mindst.first + 1;
q.push(make_pair(x.first + wall[x.first][x.second][2], x.second));
}
if(dst[x.first][x.second - wall[x.first][x.second][3]] > curdst + mindst.first + 1) {
dst[x.first][x.second - wall[x.first][x.second][3]] = curdst + mindst.first + 1;
q.push(make_pair(x.first, x.second - wall[x.first][x.second][3]));
}
if(mp[x.first + 1][x.second] != '#') {
if(dst[x.first + 1][x.second] > curdst + 1) {
dst[x.first + 1][x.second] = curdst + 1;
q.push(make_pair(x.first + 1, x.second));
}
}
if(mp[x.first][x.second + 1] != '#') {
if(dst[x.first][x.second + 1] > curdst + 1) {
dst[x.first][x.second + 1] = curdst + 1;
q.push(make_pair(x.first, x.second + 1));
}
}
if(mp[x.first - 1][x.second] != '#') {
if(dst[x.first - 1][x.second] > curdst + 1) {
dst[x.first - 1][x.second] = curdst + 1;
q.push(make_pair(x.first - 1, x.second));
}
}
if(mp[x.first][x.second - 1] != '#') {
if(dst[x.first][x.second - 1] > curdst + 1) {
dst[x.first][x.second - 1] = curdst + 1;
q.push(make_pair(x.first, x.second - 1));
}
}
}
ans = dst[t.first][t.second];
return;
}
inline void scan() {
int cur = n, dist[MAXN] = {0};
while(cur) {
for(int i = 1; i <= m; ++i) {
if(mp[cur][i] == '#') {
wall[cur][i][2] = -1;
dist[i] = 0;
} else {
wall[cur][i][2] = dist[i];
++dist[i];
}
}
--cur;
}
cur = 1; for(int i = 1; i <= m; ++i) dist[i] = 0;
while(cur <= n) {
for(int i = 1; i <= m; ++i) {
if(mp[cur][i] == '#') {
wall[cur][i][0] = -1;
dist[i] = 0;
} else {
wall[cur][i][0] = dist[i];
++dist[i];
}
}
++cur;
}
cur = 1; for(int i = 1; i <= m; ++i) dist[i] = 0;
while(cur <= m) {
for(int i = 1; i <= n; ++i) {
if(mp[i][cur] == '#') {
wall[i][cur][3] = -1;
dist[i] = 0;
} else {
wall[i][cur][3] = dist[i];
++dist[i];
}
}
++cur;
}
cur = m; for(int i = 1; i <= n; ++i) dist[i] = 0;
while(cur) {
for(int i = 1; i <= n; ++i) {
if(mp[i][cur] == '#') {
wall[i][cur][1] = -1;
dist[i] = 0;
} else {
wall[i][cur][1] = dist[i];
++dist[i];
}
}
--cur;
}
return;
}
int main() {
freopen("portal.in", "r", stdin);
freopen("portal.out", "w", stdout);
n = rd(); m = rd();
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
mp[i][j] = getc();
if(mp[i][j] == 'C') s = make_pair(i, j);
else if(mp[i][j] == 'F') t = make_pair(i, j);
}
}
scan();
bfs();
if(ans == 0x3f3f3f3f) puts("nemoguce");
else printf("%d\n", ans);
return 0;
}