在任何一个位置上 如果其转向与到达时间对p取模后的状态在之前已经存在 那就没必要再走一遍 开个四维数组标记一下即可
还有就是注意 next数组中存的方向必须与题目给定顺序一致
#include <bits/stdc++.h>
using namespace std;
const int maxn=10+10;
const int maxm=50+10;
struct node
{
int x,y,t,d;
};
queue <node> que;
int book[maxn][maxn][maxm][4];
char ch[maxn][maxn];
int n,m,p,sx,sy,ex,ey;
int bfs()
{
node cur,tmp;
int next[4][2]={0,-1,0,1,-1,0,1,0};
int i;
while(!que.empty()) que.pop();
memset(book,0,sizeof(book));
tmp.x=sx,tmp.y=sy,tmp.t=0,tmp.d=0;
que.push(tmp);
book[tmp.x][tmp.y][tmp.t%p][tmp.d]=1;
while(!que.empty()){
cur=que.front();
que.pop();
tmp=cur;
tmp.t++,tmp.d=(tmp.d+1)%4;
if(tmp.t%p==0) tmp.d=(tmp.d+3)%4;
if(!book[tmp.x][tmp.y][tmp.t%p][tmp.d]){
que.push(tmp);
book[tmp.x][tmp.y][tmp.t%p][tmp.d]=1;
}
tmp=cur;
tmp.t++,tmp.d=(tmp.d+3)%4;
if(tmp.t%p==0) tmp.d=(tmp.d+3)%4;
if(!book[tmp.x][tmp.y][tmp.t%p][tmp.d]){
que.push(tmp);
book[tmp.x][tmp.y][tmp.t%p][tmp.d]=1;
}
tmp=cur;
tmp.x+=next[tmp.d][0],tmp.y+=next[tmp.d][1],tmp.t++;
if(tmp.t%p==0) tmp.d=(tmp.d+3)%4;
if(0<=tmp.x&&tmp.x<n&&0<=tmp.y&&tmp.y<m&&!book[tmp.x][tmp.y][tmp.t%p][tmp.d]&&ch[tmp.x][tmp.y]!='*'){
que.push(tmp);
book[tmp.x][tmp.y][tmp.t%p][tmp.d]=1;
if(tmp.x==ex&&tmp.y==ey) return tmp.t;
}
tmp=cur;
tmp.t++;
if(tmp.t%p==0) tmp.d=(tmp.d+3)%4;
if(!book[tmp.x][tmp.y][tmp.t%p][tmp.d]){
que.push(tmp);
book[tmp.x][tmp.y][tmp.t%p][tmp.d]=1;
}
}
return -1;
}
int main()
{
int t,i,j,res;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&m,&p);
for(i=0;i<n;i++){
scanf("%s",ch[i]);
}
for(i=0;i<n;i++){
for(j=0;j<m;j++){
if(ch[i][j]=='@') sx=i,sy=j;
if(ch[i][j]=='$') ex=i,ey=j;
}
}
res=bfs();
if(res==-1) printf("YouBadbad\n");
else printf("%d\n",res);
}
return 0;
}