HDU 2531 Catch him(BFS:判断是否存在路径)

来源:互联网 发布:网络教育本科第二学历 编辑:程序博客网 时间:2024/05/01 13:39

HDU 2531 Catch him(BFS:判断是否存在路径)

http://acm.hdu.edu.cn/showproblem.php?pid=2531

题意:

        给你一个R*C的棋盘,但是现在不是一个格子移动了,而是多个格子组成的一个防守队员平移一个距离,但是这个组合防守队员格不可以转动身体,且身体不能触碰到O格子.最终只要身体能触碰到Q格子就算赢.

分析:

        BFS的关键在于你设计一个结构保存棋牌的每一步状态,然后根据当前状态扩展出它的所有可行不重复后继状态.最终通过判断后继是否终态来结束BFS.

      就拿这道题来说,棋牌上共4种点,但是只有D点是会动的,我们只需要保存下所有D点的坐标,即可完整保存整个棋盘的状态.所以采用如下结构来表示每个状态:

struct Node

{

    int r[21],c[21];

    int dist;

};

       正常来说,D格子最多有20个,你要判重这种具有20个坐标的状态,只能用hash了,不可能设一个20维的vis数组来判重.但是这里要注意:D球员只能平移,也就是说D格子之间的相对位置是不变的,我们只要知道最左上角的D格子,其他D格子的位置就也知道了.所以我们只需要用一个vis[r][c]来判断防守球员最左上角的那个格子是否出现在(r,c)过即可.

AC代码:

<span style="font-size:18px;">#include<cstdio>#include<cstring>#include<queue>using namespace std;const int maxn=105;int dr[]={-1,1,0,0};int dc[]={0,0,-1,1};int R,C,size;char map[maxn][maxn];bool vis[maxn][maxn];struct Node{    int r[21],c[21];    int dist;}start;int BFS(){    queue<Node> Q;    memset(vis,0,sizeof(vis));    Q.push(start);    while(!Q.empty())    {        Node node=Q.front(); Q.pop();        for(int d=0;d<4;d++)        {            int i;            Node p=node;            p.dist++;            for(i=0;i<size;i++)            {                p.r[i] += dr[d];                p.c[i] += dc[d];                if(p.r[i]<0||p.r[i]>=R||p.c[i]<0||p.c[i]>=C) break;                if(map[p.r[i]][p.c[i]]=='O') break;            }            if(i!=size) continue;       //非法            if(vis[p.r[0]][p.c[0]]) continue;            for(i=0;i<size;i++) if(map[p.r[i]][p.c[i]]=='Q') return p.dist;            vis[p.r[0]][p.c[0]]=true;            Q.push(p);        }    }    return -1;}int main(){    while(scanf("%d%d",&R,&C)==2&&R)    {        size=0;        for(int i=0;i<R;i++)        for(int j=0;j<C;j++)        {            scanf(" %c",&map[i][j]);            if(map[i][j]=='D')            {                start.r[size]=i;                start.c[size++]=j;            }        }        start.dist=0;        int ans=BFS();        if(ans==-1) printf("Impossible\n");        else printf("%d\n",ans);    }    return 0;}</span>


0 0
原创粉丝点击