題目鏈接
題意:在一個蜂巢裏,一隻小蜜蜂要從 S 點飛到 T 點。
題解:題目已經保證蜂巢的結構一定是樣例給定的框架,那麼我們可以給按照規律從左到右,從上到下給每個六邊形編號。再用bfs連邊,最後跑一遍最短路即可,思路簡單,只是連邊過程有點考驗碼力。
+---+ +---+
/ \ / \
+ +---+ +---+
\ \ / \
+ + S +---+ T +
/ \ / /
+ +---+ + +
\ \ / \
+---+ +---+ +
/ /
+ +---+ + +
\ / \
+---+ +---+ +
\ / \ /
+---+ +---+
#include<bits/stdc++.h>
using namespace std;
#define pi pair<int, int>
const int N = 1e3 + 10, M = 1e6 + 100;
char s[N * 4][N * 6];
int n, m, r, c, st, en, cnt;
int vis[M], dis[M], mp[N * 4][N * 6];
int d[7][2] = {-2, -6, -4, 0, -2, 6, 2, 6, 4, 0, 2, -6};
int di[2][2] = {-2, 6, 2, 6};
vector<int>e[M];
inline void read(){//將圖讀入
n = r * 4 + 3;
m = c * 6 + 3;
for(int i = 0; i <= n + 10; ++i)
for(int j = 0; j <= m + 10; ++j)
s[i][j]='\0', mp[i][j] = 0;
getchar();
for(int i = 1; i <= n; ++i){
char ch;
cnt = 0;
while((ch = getchar()) != '\n')
s[i][++cnt] = ch;
}
}
inline void init(){//初始化,並給中心點編號
for(int i = 0; i <= r * c + 10; ++i) {
vis[i] = 0;
e[i].clear();
}
cnt = 0;
for(int i = 1; i <= r; ++i){
int x = 3 + (i - 1) * 4, y = 5;
int dx = x, dy = y;
for(int j = 1; j <= c; ++j){
mp[dx][dy] = ++cnt;
if(s[dx][dy] == 'S') st = cnt;
if(s[dx][dy] == 'T') en = cnt;
dx = dx + di[j % 2][0];
dy = dy + di[j % 2][1];
}
}
}
inline int check(int dx, int dy, int x, int y){
if(dx < 1 || dx > n || dy < 1 || dy > m) return 0;
int mx = (dx + x) / 2;
int my = (dy + y) / 2;
if(s[mx][my] == ' ') return 2;
return 1;
}
inline void bfs(){//bfs連邊
queue<pi>q;
q.push(pi(3, 5));
while(!q.empty()){
pi t = q.front();
q.pop();
int u = mp[t.first][t.second];
if(vis[u]) continue;
vis[u] = 1;
for(int i = 0; i < 6; ++i){
int dx = t.first + d[i][0];
int dy = t.second + d[i][1];
int tmp = check(dx, dy, t.first, t.second);
if(tmp){
int v = mp[dx][dy];
if(tmp == 2){
e[u].push_back(v);
e[v].push_back(u);
}
if(!vis[v]) q.push(pi(dx, dy));
}
}
}
}
struct node{
int pos, w;
bool friend operator < (node c, node d){
return c.w > d.w;
}
};
inline void dij(){//dij最短路
priority_queue<node>q;
q.push(node{st, 1});
for(int i = 0; i < cnt + 10; ++i) vis[i] = 0, dis[i] = 1e9;
dis[st] = 1;
while(!q.empty()){
node t = q.top();
q.pop();
int u = t.pos;
if(vis[u]) continue;
vis[u] = 1;
for(auto v : e[u]){
if(dis[v] > dis[u] + 1){
dis[v] = dis[u] + 1;
q.push(node{v, dis[v]});
}
}
}
if(dis[en] == 1e9) puts("-1");
else printf("%d\n", dis[en]);
}
int main()
{
int T;
scanf("%d", &T);
while(T--){
scanf("%d%d", &r, &c);
read();
init();
bfs();
dij();
}
}