题目链接:https://codeforces.com/gym/102028/problem/F

这题就是输入处理比较恶心,先写个gets(mp[x]+1) 本地没问题,oj的编译器直接报错,真玄学,后来改成cin.get加上getline就行了。

处理数组是把点[4n+3,6m+3]映射到[n,m],最后就是bfs(之前竟然还想着最短路,压根没必要)

还有就是vis数组清空写成for循环而不是memset,就能快一倍

#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10;
typedef long long ll;
char mp[6*N+3][6*N+3];
int n,m;
int dir[6][2] ={{-2,0},{2,0},{-1,3},{-1,-3},{1,3},{1,-3}};
                //上    下    上右   上左    下右  下左
int f[2][6][2]={{{-1,0},{1,0},{0,1}, {0,-1}, {1,1},{1,-1}}, // 列为偶数
                {{-1,0},{1,0},{-1,1},{-1,-1},{0,1},{0,-1}}  // 列为奇数
                };
bool vis[N][N];
struct node
{
    int i,j,cnt;
};
int bfs(int si,int sj,int ti,int tj)
{
    int x,y; // 图中位置
    int i=si,j=sj;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            vis[i][j]=0;  //比 memset(vis,0,sizeof(vis)); 快一倍
    queue<node>q;
    while(!q.empty())q.pop();
    q.push({i,j,0});
    vis[i][j]=1;
    while(!q.empty())
    {
        node tmp=q.front();q.pop();
        int i=tmp.i;
        int j=tmp.j;
        int cnt=tmp.cnt;
        if(i==ti&&j==tj)return cnt+1;
        for(int k=0;k<6;k++) // 方向
        {
            int newi=i+f[j&1][k][0];
            int newj=j+f[j&1][k][1]; // 下一个点(ti,tj)
            if(newi<1||newi>n||newj<1||newj>m||vis[newi][newj])continue;
            if(j&1)
            {
                x=3+(i-1)*4;
                y=5+(j-1)*6;
            }
            else
            {
                x=5+(i-1)*4;
                y=11+(j-2)*6;
            }
            int tx=x+dir[k][0];
            int ty=y+dir[k][1];
            if(mp[tx][ty]==' ')
            {
                vis[newi][newj]=1;
                q.push({newi,newj,cnt+1});
            }
        }
    }
    return -1;
}
int main()
{
    ios::sync_with_stdio(false);
    int T,si,sj,ti,tj;
    cin>>T;
    string str;
    while(T--)
    {
        cin>>n>>m;
        cin.get();
        int i,j;
        for(int x=1;x<=4*n+3;x++)
        {
            getline(cin,str);  // oj的编译器用不了gets(mp[x]+1),比较玄学
            for(int p=0;str[p];p++)
                mp[x][p+1]=str[p];
        }
        for(int x=1;x<=4*n+3;x++)
            for(int y=1;y<=6*m+3;y++)
            {
                if((x-3)%4==0)
                {
                    i=(x-3)/4+1;
                    j=(y-5)/6+1;
                }
                else
                {
                    i=(x-5)/4+1;
                    j=(y-11)/6+2;
                }
                if(mp[x][y]=='S')si=i,sj=j;
                if(mp[x][y]=='T')ti=i,tj=j;
            }
        int ans=bfs(si,sj,ti,tj);
        printf("%d\n",ans);
    }
    return 0;
}