hdu 5025

来源:互联网 发布:百度经纬度坐标数据库 编辑:程序博客网 时间:2024/05/19 17:48

这题从昨天做到今天,各种错误。以前做过类似的题,是用状态压缩保存当前拥有钥匙的状态,看到这题毫不犹豫的写了。开标记数组的时候,因为钥匙最多有9把,1<<9再加上地图和蛇,发现开不下这么大。就各种剪支,然后又发现这题因为有蛇的存在,bfs第一次得到的答案并不是最优解,还得跑完整个队列才行,各种问题,一直GG。然后发现这题的钥匙必须按照顺序来拿,所以用不着状态压缩。把杀死蛇的状态压缩后,只用开1<<5 开的下,于是开4维标记数组的bfs就可以写了。(中间不想跑完整个队列,所以重载结构体后用优先队列,这样也不行)

存图时预先把图中的蛇处理成1-5的数字,这些技巧看了别人的,学到了学到了。

    #include <iostream>      #include <cstdio>      #include <cstring>      #include <queue>      #include <algorithm>            using namespace std;      int dir[4][2] = {1,0,-1,0,0,1,0,-1};     const int inf = 1<<20;      const int maxn = 105;       char g[maxn][maxn];      int d[maxn][maxn][10][33];      int n, m, sn;      int sx, sy;      struct node{          int x, y, k, s, d;          node(int xx, int yy, int kk, int ss, int dd):x(xx),y(yy),k(kk),s(ss),d(dd) {         }      };            void init() {          sn = 0;          memset(g, 0, sizeof(g));          memset(d, -1, sizeof(d));          for (int i = 1; i <= n; i++) {              for (int j = 1; j <= n; j++) {                  scanf("%c", &g[i][j]);                  if (g[i][j] == 'S') {                      g[i][j] = 'A' + sn;                      sn++;                  }                  if (g[i][j] == 'K') {                      sx = i;                       sy = j;                  }              }              getchar();          }      }      void bfs(int x, int y, int key, int snum) {          queue<node> q;          while (!q.empty())               q.pop();          int ans = inf;          node start(x, y, key, snum, 0);          q.push(start);                while (!q.empty()) {              node tmp = q.front();               q.pop();              x = tmp.x;               y = tmp.y;              key = tmp.k;              snum = tmp.s;                    if (key == m && g[x][y] == 'T')                 {  ans = min(ans, tmp.d); continue;}                    if (d[x][y][key][snum] != -1)                  continue;              d[x][y][key][snum] = tmp.d;                    for (int i = 0; i < 4; i++) {                  int tx = x + dir[i][0];                  int ty = y + dir[i][1];                  int st = g[tx][ty] - 'A';                  if (st >= 0 && st < sn) {                      if (snum & (1 << st))                                   q.push(node(tx, ty, key, snum, tmp.d + 1));                      else                          q.push(node(tx, ty, key, (snum | (1 << st)), tmp.d + 2));                   }                   else if (g[tx][ty] == '1' + key)                       q.push(node(tx, ty, key + 1, snum, tmp.d + 1));                   else if (g[tx][ty] >= '1' && g[tx][ty] < '1' + m)                       q.push(node(tx, ty, key, snum, tmp.d + 1));                   else if (g[tx][ty] == '.' || g[tx][ty] == 'K' || g[tx][ty] == 'T')                       q.push(node(tx, ty, key, snum, tmp.d + 1));                }           }          if(ans!=inf) printf("%d\n",ans);        else printf("impossible\n");    }    int main() {          while (scanf("%d %d", &n, &m) && (n || m)) {              getchar();              init();            bfs(sx, sy, 0, 0);          }          return 0;      }  


好题,因为太菜,所以超耐磨!


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 没有定速巡航跑长途怎么办 惠普笔记本驱动无法安装怎么办 狙击手遇到热追踪导弹怎么办 做完卷腹脖子疼怎么办 医疗设备销售遭遇瓶颈怎么办 给顾客加油加超了怎么办 卡密码输错两次怎么办 擤鼻涕耳朵会响怎么办 鼻子里有血丝是怎么办 怀孕8周上火了怎么办 鼻炎犯了鼻涕流不停怎么办 擤鼻涕眼睛肿了怎么办 感冒咳嗽鼻子不通气怎么办 宝宝感冒不会擤鼻涕怎么办 新生儿鼻腔里有鼻涕怎么办 宝宝鼻腔有鼻涕出不来怎么办 怀孕的人感冒了怎么办 孕37周感冒咳嗽怎么办 吹鼻涕耳朵堵了怎么办 怀孕的孔雀鱼生病了怎么办 生病了咳嗽一直不好怎么办 宝宝生病治疗后咳嗽怎么办 2个月宝宝老是生病怎么办 2个月的哈士奇生病怎么办 怀孕的猫生病了怎么办 宝宝生病咳嗽啥都不吃怎么办 怀孕了感冒了怎么办啊 2个月宝宝生病了怎么办 刚刚怀孕了就生病了怎么办 一岁多宝宝总是发烧咳嗽生病怎么办 7个月宝宝生病怎么办 4个月宝宝老是生病怎么办 孕早期嗓子有痰怎么办 鼻炎早晨起床鼻涕带血怎么办 鼻子破皮了结痂怎么办 擤鼻子耳朵好像堵住了怎么办 鼻子和脸上起皮怎么办 鼻子擦鼻涕擦红怎么办 鼻子下面擦红了怎么办 鼻子擤鼻涕破皮怎么办 哭完鼻子不通气怎么办