#include<bits/stdc++.h>usingnamespacestd;intn,m;charM[200][200];structpoint{intx,y;intv;friendbooloperator<(constpoint&a,constpoint&b){returna.v>b.v;}};intmain(){while(cin>>n>>m){intx,y,tx,ty;// read the mapfor(inti=0;i<n;i++){for(intj=0;j<m;j++){cin>>M[i][j];if(M[i][j]=='S'){x=i;y=j;}elseif(M[i][j]=='T'){tx=i;ty=j;}}}// bfspriority_queue<point>q;q.push(point{x,y,0});M[x][y]='#';while(!q.empty()){autop=q.top();q.pop();x=p.x;y=p.y;if(x==tx&&y==ty){cout<<p.v<<endl;gototag;}if(x-1>=0&&M[x-1][y]!='#'){q.push(point{x-1,y,p.v+(M[x-1][y]=='X'?2:1)});M[x-1][y]='#';}if(y+1<m&&M[x][y+1]!='#'){q.push(point{x,y+1,p.v+(M[x][y+1]=='X'?2:1)});M[x][y+1]='#';}if(x+1<n&&M[x+1][y]!='#'){q.push(point{x+1,y,p.v+(M[x+1][y]=='X'?2:1)});M[x+1][y]='#';}if(y-1>=0&&M[x][y-1]!='#'){q.push(point{x,y-1,p.v++(M[x][y-1]=='X'?2:1)});M[x][y-1]='#';}}cout<<"impossible"<<endl;tag:;}return0;}
原版迷宫问题没有怪兽,每个行动的优先级是一样的,而本题要通过怪兽需要两步,优先级产生了区别,
所以在原本bfs解法基础上,将队列改为优先队列即可。
用队列bfs,遇到怪兽就pop掉再push进去。这样就可以在怪物那里停留一步。
禁止 带有不健康的话语
同题
states怎么有人时间0内存0的?
代码竟然有23KB,这是什么神奇的方法?
[em:08][em:08][em:08][em:08][em:08][em:08]
注意读入一组新的数据后要清空优先队列。
题解
如果是原始的迷宫问题BFS,我们走过一个点P以后就把它标记掉,之后就不会走了,但这题这样做就错了,因为可能之后会有一个到P更短的路径,只是这个状态更晚出来却因为你把P标记掉了,而无法得到这个更优答案。实际上是因为原始迷宫问题每个状态所在的层数就是步数,但因为这里有怪兽的存在,层数和步数可能并不一致,也就是说如果我们某一步选择了打怪兽,那么这个新状态实际上在搜索树里是在当前状态的下两层的,而不是下一层。
下面举个例子
SMMMT
这里表示可以走的地方,M表示怪兽,ST表示起点和终点,如果我们第一个拓展的节点是M,第二个节点是,第一层结束。接着从第一层的节点扩展,第三个是M,第四个是,第五也是,这样第二层结束。一直这样进行下去,我们会发现第一个到达T的状态是从最后那个M过来的,结果是7,然后我们就把终点标记掉,之后的所有拓展就会跳过这个点了。但事实上,如果只从*从,最短是6,也就是说有一个更优的状态,但如果我们把走过的点都标记点之后不走,会错过这个更优状态。解决方法就是改用一个数组存储到某一点的最短步数,不断地去更新这个最短步数,而不是直接走过某个点之后就不走这个点了。
include
include
include
include
include
include
define REP(i,n) for(int i=0;i<n;i++)
using namespace std;
struct node {
int x,y,step;
node(int x,int y,int step):x(x),y(y),step(step) {}
node() { }
};
const int maxn = 200+5;
const int dx[4] = {1,-1,0,0};
const int dy[4] = {0,0,1,-1};
int t;
string grid[maxn];
queue Q;
int vis[maxn][maxn],n,m;
int MIN[maxn][maxn];
node st,tr;
int main() {
while(~scanf(“%d%d”,&n,&m)) {
REP(i,n) {
cin >> grid[i];
REP(j,m) {
if (grid[i][j]==’S’) st = node(i,j,0);
if (grid[i][j]==’T’) tr = node(i,j,0);
}
}
while (!Q.empty()) Q.pop();
Q.push(st);
memset(vis,0,sizeof(vis));
memset(MIN,0xff,sizeof(MIN));
vis[st.x][st.y] = 1;
MIN[st.x][st.y] = 0;
int ans = -1,flag = 0;
while (!Q.empty()) {
node u = Q.front(); Q.pop();
REP(k,4) {
int tx = u.x+dx[k],ty=u.y+dy[k];
if (tx<0 || tx>=n || ty<0 || ty>=m || grid[tx][ty]==’#’) continue;
int cost = u.step + (grid[tx][ty]==’X’?2:1);
}