zoukankan      html  css  js  c++  java
  • hdu4771 水搜索(状态压缩+bfs)

    题意:
         给你一个n*m的地图,问你从起点出发,吧所有的宝藏都捡完用的最少时间。

    思路:k <= 4,水题,直接开一个数组mark[now][x][y];now代表的是当前检宝藏的二进制压缩状态,然后就直接搜索就行了。


    #include<stdio.h>
    #include<string.h>
    #include<queue>
    
    #define N 100 + 5
    
    using namespace std;
    
    typedef struct
    {
       int x ,y ,now;
    }NODE;
    
    NODE xin ,tou;
    int mark[1<<4][N][N];
    int map[N][N];
    int dir[4][2] = {0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0};
    NODE K[5];
    int n ,m ,k;
    
    bool ok(int x ,int y ,int now)
    {
       return x <= n && x >= 1 && y <= m && y >= 1 && !mark[now][x][y] && map[x][y];
    }
    
    int BFS(int sx ,int sy)
    {
       queue<NODE>q;
       xin.x = sx ,xin.y = sy ,xin.now = 0;
       int mk = 0;
       for(int i = 1 ;i <= k ;i ++)
       if(xin.x == K[i].x && xin.y == K[i].y)
       {
          mk = i;
          break;
       }
       if(mk) xin.now = 0 | (1 << (mk - 1));                
       memset(mark ,0 ,sizeof(mark));
       q.push(xin);
       mark[xin.now][xin.x][xin.y] = 1;
       while(!q.empty())
       {
          tou = q.front();
          q.pop();
          if(tou.now == (1<<k) - 1)
          return mark[tou.now][tou.x][tou.y] - 1;
          for(int i = 0 ;i < 4 ;i ++)
          {
             xin.x = tou.x + dir[i][0];
             xin.y = tou.y + dir[i][1];
             xin.now = tou.now;
             int mk = 0;
             for(int j = 1 ;j <= k ;j ++)
             if(xin.x == K[j].x && xin.y == K[j].y)
             {
                mk = j;
                break;
             }
             if(mk) xin.now = tou.now | (1<<(mk - 1));
             if(ok(xin.x ,xin.y ,xin.now))
             {
                mark[xin.now][xin.x][xin.y] = mark[tou.now][tou.x][tou.y] + 1;
                q.push(xin);
             }
          }
       }
       return -1;
    }
    
    int main ()
    {
       int i ,j ,sx ,sy;
       char str[N];
       while(~scanf("%d %d" ,&n ,&m) && n + m)
       {
          for(i = 1 ;i <= n ;i ++)
          {
             scanf("%s" ,str);
             for(j = 1 ;j <= m ;j ++)
             {
                if(str[j-1] == '@')
                map[i][j] = 1 ,sx = i ,sy = j;
                if(str[j-1] == '.') map[i][j] = 1;
                if(str[j-1] == '#') map[i][j] = 0;
             }
          }
          scanf("%d" ,&k);
          for(i = 1 ;i <= k ;i ++)
          scanf("%d %d" ,&K[i].x ,&K[i].y);
          printf("%d
    " ,BFS(sx ,sy));
       }
       return 0;
    }
    

  • 相关阅读:
    Java怎样对一个属性设置set或get方法的快捷键
    小程序怎样控制rich-text中的<img>标签自适应
    Java中Arrys数组常用的方法
    Java 怎样实现调用其他方法
    Java保留两位小数
    解决ajax请求跨域
    rand(7) 到rand(10)
    c++生成随机数
    批量该文件名
    正则表达式(=)
  • 原文地址:https://www.cnblogs.com/csnd/p/12062926.html
Copyright © 2011-2022 走看看