zoukankan      html  css  js  c++  java
  • 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
    ",bfs(sx,sy));
     98     }
     99     return 0;
    100 }
    View Code
  • 相关阅读:
    PHP mysqli_get_client_version() 函数
    PHP mysqli_get_client_stats() 函数
    两台服务器配置互信
    (转)SQL server 容易让人误解的问题之 聚集表的物理顺序问题
    DML操作对索引的影响
    sqlserver 常用语句
    聚集索引
    表扫描
    sqltext的参数化处理
    sqlserver的执行计划
  • 原文地址:https://www.cnblogs.com/zstu-abc/p/3348364.html
Copyright © 2011-2022 走看看