题解:P1735 字母迷宫
思路
第一眼是一道 BFS,直到看到了天堂之门。所以用 DFS 写了一下,直接 TLE40。记录
相信各位停留在 A 处和 B 处的代码都会写,所以来讲一下停留在 C 处的代码。
在 C 处要停一步再走,所以可以定义一个
最后放上 AC 代码。
代码
#include <bits/stdc++.h>
using namespace std;
int n;
char a[1205][1205];
bool vis[1205][1205];
int d1[2][5]={{1,0,-1,0},{0,1,0,-1}};
int d3[2][5]={{1,1,-1,-1},{-1,1,1,-1}};
struct node{
int x,y,step;
bool flag;
};
bool flag;
void bfs(){
queue<node> q;
if(a[1][1]!='*') q.push(node{1,1,1,0});
if(a[1][n]!='*') q.push(node{1,n,1,0});
if(a[n][1]!='*') q.push(node{n,1,1,0});
while(!q.empty()){
node now=q.front();
q.pop();
if(now.x==n&&now.y==n){
//标记
flag=1;
cout<<now.step;
return;
}
if(a[now.x][now.y]=='A'){
for(int i=0;i<4;i++){
int xx=now.x+d1[0][i],yy=now.y+d1[1][i];
if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&!vis[xx][yy]&&a[xx][yy]!='*'){
vis[xx][yy]=1;
q.push(node{xx,yy,now.step+1,0});
}
}
}
else if(a[now.x][now.y]=='B'){
for(int i=0;i<4;i++){
//在B处会传送2格,乘以2
int xx=now.x+2*d1[0][i],yy=now.y+2*d1[1][i];
if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&!vis[xx][yy]&&a[xx][yy]!='*'){
vis[xx][yy]=1;
q.push(node{xx,yy,now.step+1,0});
}
}
}
else if(a[now.x][now.y]=='C'){
//对于聚气的处理
if(now.flag==0){
q.push(node{now.x,now.y,now.step+1,1});
continue;
}
//flag不为0则正常进行BFS
for(int i=0;i<4;i++){
int xx=now.x+d3[0][i],yy=now.y+d3[1][i];
if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&!vis[xx][yy]&&a[xx][yy]!='*'){
vis[xx][yy]=1;
q.push(node{xx,yy,now.step+1,0});
}
}
}
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) cin>>a[i][j];
//如果a[n][n]本身为障碍则无解
if(a[n][n]=='*'){
cout<<"No answer";
return 0;
}
bfs();
//如果没有输出则无解
if(flag==0){
cout<<"No answer";
return 0;
}
return 0;
}