【洛谷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;
}

 

posted @ 2018-07-24 15:06  yjk  阅读(136)  评论(0编辑  收藏  举报