怪兽迷宫

源代码:

#include<cstdio>
#include<cstring>
int m,n,Num(0),X[1000001],Y[1000001],i[1001][1001];
bool f[1001][1001],Vis[1001][1001];
int x[4]={0,0,1,-1};
int y[4]={1,-1,0,0};
bool Check(int Limit)
{
    memset(X,0,sizeof(X));
    memset(Y,0,sizeof(Y));
    memset(Vis,0,sizeof(Vis)); //预处理。
    int Head=0,Tail=1;
    X[1]=1;
    Y[1]=1;
    Vis[1][1]=true;
    while (Head<Tail) //BFS验证。
    {
        Head++;
        int t1=X[Head];
        int t2=Y[Head];
        for (int a=0;a<4;a++)
        {
            int T1=t1+x[a];
            int T2=t2+y[a];
            if (T1>=1&&T1<=n&&T2>=1&&T2<=m&&!Vis[T1][T2]&&!f[T1][T2]&&i[T1][T2]>=Limit)
            {
                Tail++;
                X[Tail]=T1;
                Y[Tail]=T2;
                Vis[T1][T2]=true;
                if (T1==n&&T2==m)
                  return true;
            }
        }
    }
    return false;
}
void BFS() //BFS处理每个点到最近怪兽的距离,搜索蒟蒻的我T_T。
{
    int Head=0,Tail=Num;
    while (Head<Tail)
    {
        Head++;
        int t1=X[Head];
        int t2=Y[Head];
        for (int a=0;a<4;a++) //只更新上下左右。
        {
            int T1=t1+x[a];
            int T2=t2+y[a];
            if (T1>=1&&T1<=n&&T2>=1&&T2<=m&&!i[T1][T2]&&!f[T1][T2])
            { //BFS是按队列顺序的,所以先找到肯定更优。
                i[T1][T2]=i[t1][t2]+1;
                Tail++;
                X[Tail]=T1;
                Y[Tail]=T2;
            }
        }
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int a=1;a<=n;a++)
      for (int b=1;b<=m;b++)
      {
        scanf("%d",&f[a][b]);
        if (f[a][b])
        {
            X[++Num]=a; //记录怪兽节点。
            Y[Num]=b;
        }
      }
    if (f[1][1]||f[n][m]) //特判。
    {
        printf("0");
        return 0;
    }
    BFS();
    int Left=0,Right=m+n,Ans=0;
    while (Left<=Right) //二分答案。
    {
        int Mid=(Left+Right)>>1;
        if (Check(Mid))
        {
            Ans=Mid;
            Left=Mid+1;
        }
        else
          Right=Mid-1;
    }
    printf("%d",Ans);
    return 0;
}

/*
    二分答案+BFS。
    先预处理出所有节点与怪兽的最短距离,然后BFS,看看能不能走到终点。
    遇到想不出来的题,想想二分有没有用武之地。
    搜索真是个很玄学的东西,做题还是少。
*/
posted @ 2016-11-08 06:33  前前前世。  阅读(219)  评论(0编辑  收藏  举报