hdu 1429 胜利大逃亡(续) (bfs+状态压缩)

又开始刷题了

题意:略过。

分析:主要是确定状态量,除了坐标(x,y)之外,还有一个key状态,就好比手上拿着一串钥匙。状态可以用位运算来表示:key&(x,y)表示判断有没有这扇门的钥匙,key|(x,y)表示捡起了一把钥匙。

错误:1、开标记数组mark[][][],key状态大小顺手开成key,其实应该是1<<key

        2、判断应该先判wall(),顺序颠倒倒是RE(访问越界)

    3、key<=10:只有 a-j 共10种钥匙

思考:这道题其实应该是有漏洞的,因为魔王只是查看男主是否在原位置上,并没有说明检查钥匙,如此一来男主只要在时间限定T之内找到一把钥匙,就向逃亡迈进了一步,换句话说就是状态被大幅度增加——不再是必须在T内找到出口“^”。进一步说,若魔王发现男主不在原位置,不仅把他放回原位,还还原钥匙的位置,那么如果在时间限定T内,他能够找到钥匙并返回原位,又是否算是通过了这次检查呢?以上两种情况但凡一种成立,测试样例2都可以通过。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cctype>
  4 #include<queue>
  5 #include<algorithm>
  6 using namespace std;
  7 
  8 const int MAXN=22;
  9 const int KEY=10;
 10 
 11 int dir[4][2]={0,-1,0,1,-1,0,1,0};
 12 
 13 struct Node{
 14     int x,y,t,key;
 15     Node(){}
 16     Node(int _x,int _y,int _t,int _key):x(_x),y(_y),t(_t),key(_key){}
 17 };
 18 
 19 char g[MAXN][MAXN];
 20 int mark[MAXN][MAXN][1<<KEY];
 21 queue<Node>q;
 22 
 23 int n,m,T;
 24 
 25 bool wall(int x,int y)
 26 {
 27     if(x<0||x>=n||y<0||y>=m)
 28         return true;
 29     if(g[x][y]=='*')
 30         return true;
 31     return false;
 32 }
 33 
 34 int Num(char ch)
 35 {
 36     return ch-(isupper(ch)?'A':'a');
 37 }
 38 
 39 int bfs(int sx,int sy)
 40 {
 41     while(!q.empty())
 42         q.pop();
 43 
 44     memset(mark,0,sizeof(mark));
 45     q.push(Node(sx,sy,0,0));
 46     while(!q.empty())
 47     {
 48         Node e=q.front();q.pop();
 49 
 50         if(e.t>=T)
 51             break;
 52 
 53         for(int i=0;i<4;i++)
 54         {
 55             int dx=e.x+dir[i][0];
 56             int dy=e.y+dir[i][1];
 57             int dt=e.t+1;
 58             int dkey=e.key;
 59 
 60             char ch=g[dx][dy];
 61             
 62             if(wall(dx,dy))
 63                 continue;
 64             if(dt>=T||mark[dx][dy][dkey])
 65                 continue;
 66             if(isupper(ch)&&!(dkey&(1<<Num(ch))))
 67                 continue;
 68             if(islower(ch))
 69                 dkey=dkey|(1<<Num(ch));
 70 
 71             if(g[dx][dy]=='^')
 72                 return dt;
 73 
 74             mark[dx][dy][dkey]=1;
 75             q.push(Node(dx,dy,dt,dkey));
 76         }
 77     }
 78     return -1;
 79 }
 80 
 81 int main()
 82 {
 83     while(~scanf("%d%d%d",&n,&m,&T))
 84     {
 85         for(int i=0;i<n;i++)
 86             scanf("%s",g[i]);
 87 
 88         int sx,sy,ex,ey;
 89         for(int i=0;i<n;i++)
 90             for(int j=0;j<m;j++)
 91                 if(g[i][j]=='@'){
 92                     sx=i;
 93                     sy=j;
 94                     g[i][j]='.';
 95                 }
 96 
 97         printf("%d\n",bfs(sx,sy));
 98     }
 99     return 0;
100 }
View Code

 

posted @ 2013-10-01 11:35  Thousand Sunny  阅读(246)  评论(0编辑  收藏  举报