这道题最坑的一点是,,G++一直WA,但是C++过了。。。。。EXM?????
一开始我以为可能有不记录方向的方法,但网上一搜发现,,算了还是慢慢做吧。。比较巧妙的是:
1. 把方向用数字表示,避免了字符串后续很烦的操作。
2. DFS时不能用vis数组,用break保证了每步只走一种情况并且不会陷入死循环。
附上AC代码(又丑又长QAQ):
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int>pp;
#define mkp make_pair
const int MAX=45;
int n,m;//行,列
char s[MAX][MAX];
int ans1,ans2,ans3;
pp st,en;//起点,终点
/* 0(上)
1(左) 2(右)
3(下) */
int dx[4]={-1,0,0,1};//0123
int dy[4]={0,-1,1,0};//上左右下
map<int,string>mpl,mpr;//左右优先的顺序
void init()
{ //当前方向,方向顺序
mpl[0]="1023";mpr[0]="2013";
mpl[3]="2310";mpr[3]="1320";
mpl[1]="3102";mpr[1]="0132";
mpl[2]="0231";mpr[2]="3201";
}
void dfs(int k,int sign,pp p,int step)
{ //sign==1:左 sign==2:右
int x=p.first,y=p.second;
if(s[x][y]=='E')
{
if(sign==1) ans1=step;
else ans2=step;
return;
}
string ord;//行走顺序
if(sign==1) ord=mpl[k];
else ord=mpr[k];
for(int i=0;i<4;i++)
{
int ii=ord[i]-'0';
int xx=x+dx[ii],yy=y+dy[ii];
if(xx>=0&&yy>=0&&xx<n&&yy<m&&s[xx][yy]!='#')
{
dfs(ii,sign,mkp(xx,yy),step+1);
break;//巧妙!这样一次一定只走一种情况!!同时不用标记vis!!
}
}
}
int vis[MAX][MAX];
int bfs()
{
memset(vis,0,sizeof(vis));
queue<pp>que;
que.push(st);
vis[st.first][st.second]=1;
while(!que.empty())
{
pp k=que.front();que.pop();
int x=k.first,y=k.second;
if(s[x][y]=='E')
{
return vis[x][y];
}
for(int i=0;i<4;i++)
{
int xx=x+dx[i],yy=y+dy[i];
if(xx>=0&&yy>=0&&xx<n&&yy<m&&!vis[xx][yy]&&s[xx][yy]!='#')
{ //注意写"!="而不是"=="!!(否则忽略'E'!)
vis[xx][yy]=vis[x][y]+1;
que.push(mkp(xx,yy));
}
}
}
}
int main()
{
init(); int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&m,&n);
for(int i=0;i<n;i++)
scanf("%s",s[i]);
bool sign=false;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(s[i][j]=='S') st.first=i,st.second=j;
//else if(s[i][j]=='E') en.first=i,en.second=j;
if(st.first==0)//顶端向下
dfs(3,1,st,1),dfs(3,2,st,1);
else if(st.first==n-1)//底端向上
dfs(0,1,st,1),dfs(0,2,st,1);
else if(st.second==0)//左侧向右
dfs(2,1,st,1),dfs(2,2,st,1);
else if(st.second==m-1)//右侧向左
dfs(1,1,st,1),dfs(1,2,st,1);
ans3=bfs();
printf("%d %d %d\n",ans1,ans2,ans3);
}
return 0;
}