zoukankan      html  css  js  c++  java
  • hdu1429 胜利大逃亡(续)???天天逃亡???

    题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1429/

    题目就是迷宫问题的变种,给出一张地图,上面分布着钥匙和门,一种要是只能开一种特定的门,给出起点和终点,问在t时间内是否能够走到终点。这个问题显然是要用bfs解决,但是状态量除了位置之外还有钥匙,持有的钥匙不同到达同一个位置也是状态空间中的一种不同的状态,所以用三维记录状态,状态的记录可以用二进制进行状态压缩,毕竟钥匙只有有和无两种状态。

    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned int ui;
     4 typedef long long ll;
     5 typedef unsigned long long ull;
     6 #define pf printf
     7 #define mem(a,b) memset(a,b,sizeof(a))
     8 #define prime1 1e9+7
     9 #define prime2 1e9+9
    10 #define pi 3.14159265
    11 #define lson l,mid,rt<<1
    12 #define rson mid+1,r,rt<<1|1
    13 #define scand(x) scanf("%llf",&x) 
    14 #define f(i,a,b) for(int i=a;i<=b;i++)
    15 #define scan(a) scanf("%d",&a)
    16 #define dbg(args) cout<<#args<<":"<<args<<endl;
    17 #define inf 0x3f3f3f3f
    18 #define maxn 25
    19 int n,m,t;
    20 char Map[maxn][maxn];
    21 int sx,sy,tx,ty;
    22 bool vis[maxn][maxn][(1<<10)];//钥匙最多是2^10-1种状态 
    23 int dir[][2]={0,1,0,-1,1,0,-1,0};
    24 struct node{
    25     int x,y,step;
    26     int key;//钥匙也是一种状态,所以考虑状态压缩存储有限的钥匙的状态 
    27     node(int x,int y,int s,int key):x(x),y(y),step(s),key(key){}
    28     node(){}
    29 };
    30 node cur,nxt;
    31 int bfs()
    32 {
    33     queue<node>q;//选择队列这种结构在于队列前面的结点step值小,step是连续变化的值
    34     q.push(node(sx,sy,0,0));
    35     vis[sx][sy][0]=1; 
    36     while(!q.empty())
    37     {
    38         cur=q.front();
    39         q.pop();
    40         if(cur.x==tx&&cur.y==ty&&cur.step<t)
    41         {
    42             return cur.step;
    43         }
    44         f(i,0,3)
    45         {
    46             nxt=cur;
    47             nxt.x+=dir[i][0];
    48             nxt.y+=dir[i][1];
    49             nxt.step++;
    50             if(nxt.x<1||nxt.x>n||nxt.y<1||nxt.y>m||Map[nxt.x][nxt.y]=='*')continue;
    51             if(vis[nxt.x][nxt.y][nxt.key])continue;//相对于非门非钥匙的位置,首先判断是否已经入队 
    52             char c=Map[nxt.x][nxt.y];
    53             if(c>='a'&&c<='j')
    54             {
    55                 nxt.key|=(1<<(c-'a'));//用二进制将状态压缩进每一位中 
    56                 if(vis[nxt.x][nxt.y][nxt.key])continue;
    57             }
    58             if(c>='A'&&c<='J')
    59             {
    60                 if(!(nxt.key&(1<<(c-'a'))))continue;//遇到门的时候钥匙的状态不会改变,所以不必重复检查状态是否发生变化 
    61             }
    62             vis[nxt.x][nxt.y][nxt.key]=1;//上面筛选掉所有不能入队的状态,剩余的状态都必须进队 
    63                 q.push(nxt);
    64         }
    65     }
    66     return -1;
    67 }
    68 int main()
    69 {
    70     //freopen("input.txt","r",stdin);
    71     //freopen("output.txt","w",stdout);
    72     std::ios::sync_with_stdio(false);
    73     while(scanf("%d%d%d",&n,&m,&t)!=EOF)
    74     {
    75         mem(vis,false); 
    76         f(i,1,n)
    77             f(j,1,m)
    78             {
    79                 scanf(" %c",&Map[i][j]);
    80                 if(Map[i][j]=='@')sx=i,sy=j;
    81                 if(Map[i][j]=='^')tx=i,ty=j;
    82             }
    83             pf("%d
    ",bfs());
    84     }
    85  } 
  • 相关阅读:
    用OSCache进行缓存对象
    oscache的使用
    WHM(Web Hosting Manager)/CPANEL 设置及linux 文件权限 经验
    辗转相除法求最大公约数和最小公倍数【gcd】
    u6填写入库单单据报错
    账表名称无法显示
    商贸通反利怎么计算
    UFO报表转换不成功!请检查文件版本或使用DOS文件转换工具
    备份计划不执行
    821升级U6报错
  • 原文地址:https://www.cnblogs.com/randy-lo/p/12511804.html
Copyright © 2011-2022 走看看