其实这道题就是一个带有方向的bfs,只要在普通的数组后面加上一个方向即可bfs然后AC
注意点:如果一个点重复以同一个方向进入就得跳过这个点(我因为这个一直卡着)
一个点有可能重复访问,因为方向不一样,所以要在vis数组也加一个方向
输出格式很重要,每10个换一行,而且要在前面加两个空格
每次进入一个点后要考虑能走的方向,可以编写函数来转换成东南西北
下面是AC代码
#include<bits/stdc++.h>
using namespace std;
int n,m;
int headx,heady,tarx,tary;
int dx[]= {-1,0,0,1};
int dy[]= {0,-1,1,0};
int vis[200][200][200];//记录访问状态
vector<int>chess[100][100][10];//记录迷宫的x,y,进入方向,能走的方向
string a;
struct node//记录答案的node
{
int x;
int y;
node(int x,int y):x(x),y(y) {}
};
struct pos//每个点的结构体
{
int x;
int y;
int d;
vector<node>way;//记录这个点走的路径
pos(int x,int y,int d):x(x),y(y),d(d) {}
};
vector<node>ans;//记录答案
int ex(char a)//将字母转换成数字
{
if(a=='N')
return 1;
else if(a=='S')
return 4;
else if(a=='W')
return 2;
else if(a=='E')
return 3;
}
int dir(char in,char can)//将进入方向和能走的方向转换成整体的东南西北方向
{
if(can=='F')return ex(in);
else if(can=='L')
{
if(in=='N')
return 2;
else if(in=='S')
return 3;
else if(in=='W')
return 4;
else if(in=='E')
return 1;
}
else
{
if(in=='N')
return 3;
else if(in=='S')
return 2;
else if(in=='W')
return 1;
else if(in=='E')
return 4;
}
}
bool solve()
{
string d;
int x,y;
ans.clear();//初始化
memset(vis,0,sizeof(vis));
for(int i=0;i<10;i++)
{
for(int j=0;j<10;j++)
{
for(int k=0;k<6;k++)
chess[i][j][k].clear();
}
}
cin>>headx>>heady>>d>>tarx>>tary;//存储起点终点
string di;
while(cin>>x)
{
if(x==0)break;//输入结束
cin>>y;
while(cin>>di)//存储方向
{
if(di=="*")break;
for(int i=1; i<di.length(); i++)
{
chess[x][y][ex(di[0])].push_back(dir(di[0],di[i]));
}
}
}
queue<pos>q;
pos k=pos(headx+dx[ex(d[0])-1],heady+dy[ex(d[0])-1],ex(d[0]));//起点走出的第一个点
k.way.push_back(node(headx,heady));
q.push(k);
while(!q.empty())
{
pos t=q.front();
q.pop();if(vis[t.x][t.y][t.d])continue;//如果走入循环就跳过
vis[t.x][t.y][t.d]=1;//标记已经走过的状态
t.way.push_back(node(t.x,t.y));//记录路径
if(t.x==tarx&&t.y==tary)//到终点处理
{
ans=t.way;
return true;
}
x=t.x;
y=t.y;
for(int j=0; j<chess[x][y][t.d].size(); j++)//遍历能走的方向
{
int xx,yy,dd;
xx=x+dx[chess[x][y][t.d][j]-1];
yy=y+dy[chess[x][y][t.d][j]-1];
dd=chess[x][y][t.d][j];
pos te=t;
te.x=xx;
te.y=yy;
te.d=dd;
q.push(te);
}
}return false;
}
void show()
{
for(int i=0;i<ans.size();i++)
{
if((i+1)%10!=1)cout<<" ";//非开头
else cout<<" ";//开头
printf("(%d,%d)",ans[i].x,ans[i].y);
if((i+1)%10==0&&(i+1)!=ans.size())cout<<endl;//防止长度刚好是10的倍数导致换行两次
}cout<<endl;
}
int main()
{
//freopen("1.txt","w",stdout);
string name;
while(cin>>name)
{
if(name=="END")break;
cout<<name<<endl;
if(solve())show();
else cout<<" No Solution Possible\n";
}
return 0;
}