【POJ2157】Maze

来源:互联网 发布:nginx http host 编辑:程序博客网 时间:2024/05/22 01:41

题目链接:http://poj.org/problem?id=2157
题解:
BFS爆搜
建一个bool1数组表示一个门是否走过,一个bool2数组表示任意一个点是否走过
每次走到一个钥匙,该钥匙数+1,如果这个钥匙对应的门曾经到过,而且钥匙数够了,把门放进队列里,没有到过就个普通的点一样处理
如果走到一个门,如果钥匙数等于零,那么把这个门加进队列里,如果不为零,标记为到过这个门

感觉思路没问题,POJ的discuss里的数据也都过了,可就是A不了,怒改4h水过…
这种爆搜题真是无话可说…….

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;int n,m;int vis[101][101],vis_door[101][101];char map[101][101];int x [ 5 ] = { 1,-1, 0, 0 } ;int y [ 5 ] = { 0, 0, 1,-1 } ;struct node{    int x,y;};struct key{    int tot,cnt;}k[101];int main(){    while(~scanf("%d%d",&n,&m)&&(n||m))    {        bool flag=0,a;        memset(k,0,sizeof(k));        memset(vis,0,sizeof(vis));        memset(vis_door,0,sizeof(vis_door));        for(int i=1;i<=n;i++) scanf("%s",map[i]+1);        queue<node> q;        node st,t,p;        for(int i=1;i<=n;i++)            for(int j=1;j<=m;j++)                if(map[i][j]=='S') st.x=i,st.y=j;                else if(map[i][j]=='X') vis[i][j]=1;                else if(map[i][j]>='a'&&map[i][j]<='e') k[map[i][j]-'a'].tot++;        q.push(st);        while(!q.empty())        {            p=q.front();            q.pop();            for(int i=0;i<=3;i++)            {                int nx=p.x+x[i];                int ny=p.y+y[i];                if(nx>=1&&nx<=n&&ny>=1&&ny<=m)                    if(!vis[nx][ny])                    {                        if(map[nx][ny]>='a'&&map[nx][ny]<='e')                        {                            if(++k[map[nx][ny]-'a'].cnt==k[map[nx][ny]-'a'].tot&&k[map[nx][ny]-'a'].cnt>=1)                            {                                for(int ii=1;ii<=n;ii++)                                    for(int jj=1;jj<=m;jj++)                                    if(map[ii][jj]==map[nx][ny]+'A'-'a')                                    {                                        node hh;                                        hh.x=ii;                                        hh.y=jj;                                        if(vis_door[ii][jj])                                        {                                            q.push(hh);                                            vis[ii][jj]=1;                                          }                                    }                            }                            t.x=nx;                            t.y=ny;                            q.push(t);                            vis[nx][ny]=1;                        }                        else if(map[nx][ny]=='G')                        {                            flag=1;                            break;                        }                        else if(map[nx][ny]>='A'&&map[nx][ny]<='E')                        {                            if(k[map[nx][ny]-'A'].tot==k[map[nx][ny]-'A'].cnt&&k[map[nx][ny]-'A'].cnt>=1)                            {                                t.x=nx;                                t.y=ny;                                q.push(t);                                vis[nx][ny]=1;                            }                            else vis_door[nx][ny]=1;                        }                        else if(map[nx][ny]=='.')                        {                            t.x=nx;                            t.y=ny;                            q.push(t);                            vis[nx][ny]=1;                        }                    }            }        }        if(flag) printf("YES\n");        else printf("NO\n");    }    return 0;}
原创粉丝点击