zoukankan      html  css  js  c++  java
  • HDU 4828 小明系列故事——捉迷藏

    漂亮妹子点击就送:http://acm.hdu.edu.cn/showproblem.php?pid=4528

    Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 2051    Accepted Submission(s): 618

    Problem Description
      小明的妈妈生了三个孩子,老大叫大明, 老二叫二明, 老三..., 老三自然就叫小明了。
      一天,小明的妈妈带小明兄弟三人去公园玩耍,公园里面树木很多,有很多地方可以藏身, 于是他们决定玩捉迷藏。经过几轮的猜拳后,第一轮是小明来找其他两个人,游戏规则很简单:
      只要小明可以在规定的时间内找到他们就算小明获胜,并且被发现的两个人猜拳决定谁在下一轮负责找人;如果在规定的时间内只找到一个人,那么没有被发现的人获胜,被找到的人下一轮负责找人;如果在规定的时间内一个人都没有找到,则小明失败了,下一轮还是他来找人。现在小明想知道,在规定时间内,自己是否可以找到所有的人,现在他想请你来帮忙计算一下。
      为了简单起见,把公园看成是n行m列的矩阵,其中’S’表示小明,’D’表示大名,’E’表示二明,’X’表示障碍物,’.’表示通路。这里,我们把发现定义为,可以直接看到对方, 也就是说两个人在同一行或者同一列,并且中间没有障碍物或者没有其他人就可以看到对方。并且假设,大明,二明藏好以后就不会再改变位置,小明每个单位时间可以从当前的位置走到相邻的四个位置之一,并且不会走出公园。
     
    Input
    测试数据第一行是一个正整数T,表示有T组测试数据。
    每一组测试数据首先是三个正整数n,m,t,分别表示行数、列数和规定的时间,接下来n行,每行m个上述的字符,并且保证有且只有一个’S’,一个’E’,一个’D’。

    [Technical Specification]
    T < 200
    3 <= n, m <= 100
    0 <= t <= 100
     
    Output
    每组先输出一行Case c:(c表示当前的组数,从1开始计数);
    接下来一行,如果小明可以在规定时间内找到所有的人,则输出最少需要的时间,否则输出-1。
     
    Sample Input
    3
    5 6 3
    XXD...
    ....E.
    ....X.
    ....S.
    ......
    5 6 3
    XDX...
    ....E.
    ......
    ....S.
    ......
    5 6 8
    XXDX..
    .XEX..
    ......
    ....S.
    ......
     
    Sample Output
    Case 1:
    -1
    Case 2:
    3
    Case 3:
    -1
     
     
    //一开始竟然想四个方向倍增。。。晕
    //因为是在同一行同一列看到对方就可以,所以我们先对大明和二明在四个方向上进行处理,
    //标记那些和它同行或同列且之间没有障碍的格子
    //表示在这个格子上可一看到大明或者二明,用flag1[][]和flag2[][]来标记 
    //但是要注意的是,一个格子我们可以走两遍(找完大明再找二明)
    //所以,用vis[x][y][2][2]数组表示在(x,y)这个点可以看见的人 
    
    ////但是我预处理写的也是够233 
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std;
    
    const int N=105;
    
    int T,n,m,tim;
    int DX,DY,EX,EY,SX,SY;
    char map[N][N];
    bool flag1[N][N],flag2[N][N],vis[N][N][2][2];
    struct STA
    {
        int x,y;
        int tim;
        bool f1,f2;
    }now,tmp;
    int cx[4]={0,0,1,-1};
    int cy[4]={1,-1,0,0};
    
    queue<STA> que;
    inline int bfs()
    {
        int x,y,xx,yy;
        now.f1=flag1[SX][SY];
        now.f2=flag2[SX][SY];
        if(now.f1&&now.f2)
            return 0;
        now.tim=0;
        now.x=SX,now.y=SY;
        vis[SX][SY][now.f1][now.f2]=1;
        while(!que.empty())
            que.pop();
        que.push(now);
        while(!que.empty())
        {
            now=que.front(),que.pop();
            if(now.tim>=tim)
                break;
            x=now.x,y=now.y;
            for(int i=0;i<4;++i)
            {
                xx=x+cx[i],yy=y+cy[i];
                if(xx<1||xx>n||yy<1||yy>m||map[xx][yy]!='.')
                    continue;
                tmp.x=xx,tmp.y=yy,tmp.tim=now.tim+1;
                tmp.f1=now.f1||flag1[xx][yy];
                tmp.f2=now.f2||flag2[xx][yy];
                if(tmp.f1&&tmp.f2)
                    return tmp.tim;
                if(vis[xx][yy][tmp.f1][tmp.f2])
                    continue;
                vis[xx][yy][tmp.f1][tmp.f2]=1;
                que.push(tmp);
            }
        }
        return -1;
    }
    
    inline void init()        //预处理可以看见的位置 
    {
        flag1[DX][DY]=1;
        flag2[EX][EY]=1;
        for(int i=DX+1;i<=n;++i)
        {
            if(map[i][DY]=='S')
            {
                flag1[i][DY]=1;
                break;
            }
            if(map[i][DY]!='.')
                break;
            flag1[i][DY]=1;
        }
        for(int i=DX-1;i;--i)
        {
            if(map[i][DY]=='S')
            {
                flag1[i][DY]=1;
                break;
            }
            if(map[i][DY]!='.')
                break;
            flag1[i][DY]=1;
        }
        for(int i=DY+1;i<=m;++i)
        {
            if(map[DX][i]=='S')
            {
                flag1[DX][i]=1;
                break;
            }
            if(map[DX][i]!='.')
                break;
            flag1[DX][i]=1;
        }
        for(int i=DY-1;i;--i)
        {
            if(map[DX][i]=='S')
            {
                flag1[DX][i]=1;
                break;
            }
            if(map[DX][i]!='.')
                break;
            flag1[DX][i]=1;
        }
        for(int i=EX+1;i<=n;++i)
        {
            if(map[i][EY]=='S')
            {
                flag2[i][EY]=1;
                break;
            }
            if(map[i][EY]!='.')
                break;
            flag2[i][EY]=1;
        }
        for(int i=EX-1;i;--i)
        {
            if(map[i][EY]=='S')
            {
                flag2[i][EY]=1;
                break;
            }
            if(map[i][EY]!='.')
                break;
            flag2[i][EY]=1;
        }
        for(int i=EY+1;i<=m;++i)
        {
            if(map[EX][i]=='S')
            {
                flag2[EX][i]=1;
                break;
            }
            if(map[EX][i]!='.')
                break;
            flag2[EX][i]=1;
        }
        for(int i=EY-1;i;--i)
        {
            if(map[EX][i]=='S')
            {
                flag2[EX][i]=1;
                break;
            }
            if(map[EX][i]!='.')
                break;
            flag2[EX][i]=1;
        }
    }
    
    int main()
    {
        scanf("%d",&T);
        for(int k=1;k<=T;++k)
        {
            memset(flag1,0,sizeof(flag1));
            memset(flag2,0,sizeof(flag2));
            memset(vis,0,sizeof(vis));
            scanf("%d%d%d",&n,&m,&tim);
            for(int i=1;i<=n;++i)
            {
                scanf("%s",map[i]+1);
                for(int j=1;j<=m;++j)
                {
                    if(map[i][j]=='D')
                        DX=i,DY=j;
                    else if(map[i][j]=='E')
                        EX=i,EY=j;
                    else if(map[i][j]=='S')
                        SX=i,SY=j;
                }
            }
            init();
            printf("Case %d:
    %d
    ",k,bfs());
        }
        return 0;
    }
    /*
    1 2 2 2
    D.
    SE
    */
  • 相关阅读:
    防删没什么意思啊,直接写废你~
    绝大多数情况下,没有解决不了的问题,只有因为平时缺少练习而惧怕问题的复杂度,畏惧的心理让我们选择避让,采取并不那么好的方案去解决问题
    Java 模拟面试题
    Crossthread operation not valid: Control 'progressBar1' accessed from a thread other than the thread it was created on
    一步步从数据库备份恢复SharePoint Portal Server 2003
    【转】理解 JavaScript 闭包
    Just For Fun
    The database schema is too old to perform this operation in this SharePoint cluster. Please upgrade the database and...
    Hello World!
    使用filter筛选刚体碰撞
  • 原文地址:https://www.cnblogs.com/lovewhy/p/8743549.html
Copyright © 2011-2022 走看看