HDU 4528 小明系列故事——捉迷藏

来源:互联网 发布:网络老虎机破解技巧 编辑:程序博客网 时间:2024/06/05 03:59

题目链接~~>

做题感悟:这题需要逆向思维,先预处理一下就好。

解题思路:先预处理一下将可以看到 D 与 E 的点标记一下,这样 bfs()遍历迷宫时就可以节省很多时间,还要注意:可以重复走走过的点只要用二进制压缩一下就好。

代码:

#include<stdio.h>#include<iostream>#include<map>#include<stack>#include<string>#include<string.h>#include<stdlib.h>#include<math.h>#include<vector>#include<queue>#include<algorithm>using namespace std ;#define lld __int64const double PI = 3.1415926 ;const double esp = 1e-4 ;const int  md= 2810778 ;const int MX = 105 ;int n,m,t ;char s[MX][MX] ;bool va[MX][MX],vb[MX][MX],vis[MX][MX][5] ;int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1} ;struct node{    int x,y,step,key ;} ;bool search(int x,int y) // 判断边界{    if(x<0||y<0||x>=n||y>=m||s[x][y]=='X')        return false ;        return true ;}void init(int dx,int dy,int ex,int ey)// 预处理{    for(int i=dx+1 ;i<n ;i++)        if(s[i][dy]=='.')           va[i][dy]=true ;        else if(s[i][dy]=='S')        {           va[i][dy]=true ;           break ;        }        else  break ;    for(int i=dx-1 ;i>=0 ;i--)        if(s[i][dy]=='.')             va[i][dy]=true ;        else if(s[i][dy]=='S')        {            va[i][dy]=true ;            break ;        }        else break ;    for(int j=dy+1 ;j<m ;j++)       if(s[dx][j]=='.')           va[dx][j]=true ;       else if(s[dx][j]=='S')       {           va[dx][j]=true ;           break ;       }       else break ;    for(int j=dy-1 ;j>=0 ;j--)       if(s[dx][j]=='.')           va[dx][j]=true ;       else if(s[dx][j]=='S')       {           va[dx][j]=true ;           break ;       }       else  break ;    for(int i=ex+1 ;i<n ;i++)       if(s[i][ey]=='.')           vb[i][ey]=true ;       else if(s[i][ey]=='S')       {           vb[i][ey]=true ;           break ;       }       else  break ;    for(int i=ex-1 ;i>=0 ;i--)      if(s[i][ey]=='.')             vb[i][ey]=true ;      else  if(s[i][ey]=='S')      {          vb[i][ey]=true ;          break ;      }      else break ;    for(int j=ey+1 ;j<m ;j++)      if(s[ex][j]=='.')          vb[ex][j]=true ;      else if(s[ex][j]=='S')      {          vb[ex][j]=true ;          break ;      }      else break ;    for(int j=ey-1 ;j>=0 ;j--)      if(s[ex][j]=='.')           vb[ex][j]=true ;      else if(s[ex][j]=='S')      {          vb[ex][j]=true ;          break ;      }      else  break ;}int bfs(int x,int y){    memset(vis,false,sizeof(vis)) ;    int sx,sy,key ;    queue<node>q ;    node curt,next ;    curt.x=x ;    curt.y=y ;    curt.key=0 ;    if(va[x][y])       curt.key=curt.key|1 ;    if(vb[x][y])       curt.key=curt.key|2 ;    curt.step=0 ;    vis[x][y][curt.key]=true ;    q.push(curt) ;    while(!q.empty())    {        curt=q.front() ;        q.pop() ;        if(curt.step>t) continue ;        if(curt.key==3) // 判断是否找到两个人            return curt.step ;        for(int i=0 ;i<4 ;i++)        {            next.x=sx=curt.x+dx[i] ;            next.y=sy=curt.y+dy[i] ;            next.key=key=curt.key ;            next.step=curt.step+1 ;            if(search(sx,sy)&&s[sx][sy]!='D'&&s[sx][sy]!='E')            {                if((key&1)==0&&va[sx][sy]) // 没看见过第一个人&&在这点可以看见第一个                       key=key|1 ;                if((key&2)==0&&vb[sx][sy]) // 没看见过第二个人&&在这点可以看见第二个人                      key=key|2 ;                if(!vis[sx][sy][key]) // 没有走过这点                {                    vis[sx][sy][key]=true ;                    next.key=key ;                    q.push(next) ;                }            }        }    }    return -1 ;}int main(){    int Tx,q=1 ;    scanf("%d",&Tx) ;    while(Tx--)    {        scanf("%d%d%d",&n,&m,&t) ;        int dx,dy,ex,ey,sx,sy ;        for(int i=0 ;i<n ;i++)        {            scanf("%s",s[i]) ;            for(int j=0 ;j<m ;j++)            {                if(s[i][j]=='D')                {                    dx=i ;                    dy=j ;                }                else if(s[i][j]=='E')                {                    ex=i ;                    ey=j ;                }                else if(s[i][j]=='S')                {                    sx=i ;                    sy=j ;                }            }        }        memset(va,false,sizeof(va)) ;        memset(vb,false,sizeof(vb)) ;        init(dx,dy,ex,ey) ;        printf("Case %d:\n%d\n",q++,bfs(sx,sy)) ;    }    return 0 ;}


 

0 0
原创粉丝点击