【洛谷P3818】小A和uim之大逃离 II
小A和uim之大逃离 II
比较裸的搜索,vis[i][j]再加一层[0/1]表示是否使用过魔液
转移时也将是否使用过魔液记录下来,广搜即可
#include<iostream> #include<cstring> #include<cstdio> using namespace std; #define N 1010 int n,m,t[N][N][2],que[N*10000][2],head,tail; bool used[N*N],vis[N][N]; char map[N][N]; int dx[6]={0,0,0,-1,1,0},dy[6]={0,-1,1,0,0,0}; int main() { scanf("%d%d%d%d",&n,&m,&dx[5],&dy[5]); for(int i=1;i<=n;i++) scanf("%s",map[i]+1); que[++tail][0]=1; que[tail][1]=1; t[1][1][0]=1; while(head<tail){ int x=que[++head][0]; int y=que[head][1]; int f=used[head]; if(x==n&&y==m) break; for(int i=1;i<=5;i++){ int nx=x+dx[i],ny=y+dy[i]; if(nx<1||nx>n||ny<1||ny>m) continue; if(map[nx][ny]!='.'||t[nx][ny][f]) continue; if(i==5&&used[head]) break; bool nf=i==5?1:f; t[nx][ny][nf]=t[x][y][f]+1; que[++tail][0]=nx; que[tail][1]=ny; used[tail]=nf; } } if(t[n][m][1]||t[n][m][0]){ int ans=0x7fffffff; if(t[n][m][1]) ans=t[n][m][1]; if(t[n][m][0]) ans=min(ans,t[n][m][0]); printf("%d\n",ans-1); } else puts("-1"); return 0; }