摘自:
一看题目,像个搜索
再一看,像个广度优先搜索
既然是BFS,那我们首先要搞出一个(一堆)队列
那问题是队列里咱们存啥呢???
首先,按照广搜解决“迷宫问题”的国际惯例,肯定要先把坐标和步数存到里面!
可是,这似乎不大够?
因为荆轲还有两种技能:隐身和瞬移。
隐身:balabala……
瞬移:balabala……
现在给出咸阳城的地图,请计算荆轲到达秦王所在点所需的最短时间。此外,在所用时间相同情况下,荆轲希望使用的两种技能总次数尽可能少;在所用时间与技能次数相同情况下,荆轲希望使用的隐身次数尽可能少。
emmmmm,还要把隐身和瞬移的使用次数存下来~
啊,要存这么多东西……这时候,结构体就要派上用场啦!
struct qwq{int x,y,yx,sy,s;//x,y——对应的坐标//s——走到这一步的步数//yx——隐形使用次数//sy——瞬移使用次数//(都是用拼音写的呢)
};
queue <qwq> q;
当然,我们要在茫茫多的方案中选择一个最优解——所以,我们要写一个函数(算是取min吧……),来选择一个最优解
qwq minq(qwq a,qwq b){if(a.s!=b.s)return a.s<b.s?a:b;//优先选择步数更小的if(a.yx+a.sy!=b.yx+b.sy)return a.yx+a.sy<b.yx+b.sy?a:b;//如果步数相等,选择一个技能使用更少的return a.yx<b.yx?a:b;//都相等?!那就选一个隐身用的更少的吧
}
qwq ans=(qwq){0,0,233333333,233333333,233333333};//顺便把初始化的ans放出来,当然要挑个大的
……
#include<bits/stdc++.h>
using namespace std;
struct qwq{int x,y,yx,sy,s;
};
qwq minq(qwq a,qwq b){if(a.s!=b.s)return a.s<b.s?a:b;if(a.yx+a.sy!=b.yx+b.sy)return a.yx+a.sy<b.yx+b.sy?a:b;return a.yx<b.yx?a:b;
}
bool vis[355][355][20][20],look[355][355];
int tag[355][355];
int n,m,c1,c2,d;
int map[355][355];
const int dx[8]={1,0,-1,0,1,-1,-1,1},dy[8]={0,1,0,-1,1,1,-1,-1};
void lookaround(int x,int y,int k){for(int i=0;i<=k;i++){tag[max(x-i,1)][max(y-(k-i),1)]++; tag[max(x-i,1)][min(y+(k-i),m)+1]--;tag[min(x+i,n)][max(y-(k-i),1)]++;tag[min(x+i,n)][min(y+(k-i),m)+1]--;}
}
int sx,sy,ex,ey;
queue <qwq> q;
qwq ans=(qwq){0,0,233333333,233333333,233333333};
void bfs(){while(!q.empty()){qwq fro=q.front();q.pop();if(fro.s>ans.s)continue;if(fro.x==ex&&fro.y==ey){ans=minq(ans,fro);continue;} for(int i=0;i<8;i++){int nx=fro.x+dx[i];int ny=fro.y+dy[i];if(nx<1||nx>n||ny<1||ny>m||map[nx][ny]>0)continue;if(look[nx][ny]){if(vis[nx][ny][fro.yx+1][fro.sy]||fro.yx+1>c1)continue;vis[nx][ny][fro.yx+1][fro.sy]=1;q.push((qwq){nx,ny,fro.yx+1,fro.sy,fro.s+1});}else{if(vis[nx][ny][fro.yx][fro.sy])continue;vis[nx][ny][fro.yx][fro.sy]=1;q.push((qwq){nx,ny,fro.yx,fro.sy,fro.s+1}); }}if(fro.sy+1>c2)continue;for(int i=0;i<4;i++){int nx=fro.x+dx[i]*d;int ny=fro.y+dy[i]*d;if(nx<1||nx>n||ny<1||ny>m||map[nx][ny]>0)continue;if(look[nx][ny]){if(vis[nx][ny][fro.yx+1][fro.sy+1]||fro.yx+1>c1)continue;vis[nx][ny][fro.yx+1][fro.sy+1]=1;q.push((qwq){nx,ny,fro.yx+1,fro.sy+1,fro.s+1});}else{if(vis[nx][ny][fro.yx][fro.sy+1])continue;vis[nx][ny][fro.yx][fro.sy+1]=1;q.push((qwq){nx,ny,fro.yx,fro.sy+1,fro.s+1}); } }}
}
int main(){ios::sync_with_stdio(false);cin>>n>>m>>c1>>c2>>d;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){string s;cin>>s;if(s[0]=='S'){sx=i,sy=j;map[i][j]=-1;q.push((qwq){sx,sy,0,0,0});vis[i][j][0][0]=1;}else if(s[0]=='T'){ex=i,ey=j;map[i][j]=-2;}else if(s[0]=='.')map[i][j]=0;else{int x=0;for(int i=0;i<s.size();i++)x=(x<<1)+(x<<3)+(s[i]^'0');map[i][j]=x;lookaround(i,j,x-1);}}}for(int i=1;i<=n;i++){int sum=0;for(int j=1;j<=m;j++){sum+=tag[i][j]; if(sum>0)look[i][j]=1; }} bfs();if(ans.s==233333333)printf("-1");else printf("%d %d %d",ans.s,ans.yx,ans.sy);return 0;
}