题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3713

题目:两个小球同时在两个迷宫里走,求使两个小球同时到达终点的最短走法。小球不能越出迷宫界,也不能掉到洞里。有的格子有挡板,如果挡板阻碍了小球的移动,则小球会呆在原地不动。如果有多组解,输出字典序最小的那个。

分析:裸BFS,但是我错了很多遍,因为之前有些地方没想清楚。

1,一开始我把 [小球被挡板阻碍] 和 [小球越界,小球掉到洞里] 放到一起考虑,写了个判断,都认为它们是不可达的。这是错误的。实际上这是两种情况,因为题目中有说:The barriers may make the commands take no effect, i.e., the ball does NOT move if there is a barrier on the way. 挡板只是抵消了这一步的命令,它可以继续执行下一步命令,并不是不可达。而[小球越界,小球掉到洞里] 才是不可达的情况。所以应当先判断这一步命令对两个小球是否分别有效,再判断它们是否越界或掉到洞里。

2,在判断小球能否移动到下一个格子上,有一个比较坑爹的地方。

举例说明:如果小球所在的格子是A,B是A正上方的格子,若A上方有挡板,那么它是不能由A直接向上移动到B。

我是先把小球移动到B,再判断B正下方是否有挡板,若有,则它是不能由A直接向上移动到B。

按理说这两种判断方式应该是一样的,也就是说,A上方有挡板=B下方有挡板。但事实上只有第一种判断方法是正确的,第二种是错误的,我WA了好几次才该对。

也就是说A上方有挡板≠B下方有挡板,至于为啥,貌似题目里面也没说清楚。

  1 #include <cstdio>
  2 #include <cstring>
  3
  4 const int MAXN = 8;
  5 const int MAXSIZE = 10000 + 1;
  6 const char move[5] = "DLRU";   //保证字典序最小
  7 const int dx[] = { 1, 0, 0, -1 };
  8 const int dy[] = { 0, -1, 1, 0 };
  9
 10 int map1[MAXN][MAXN];
 11 int map2[MAXN][MAXN];
 12 int start_x1, start_y1, start_x2, start_y2;
 13 int fa[MAXSIZE];         //记录移动路线
 14 bool vis[MAXSIZE];       //判重
 15 int queue[MAXSIZE];      //队列
 16 int dir[MAXSIZE];        //记录移动方向
 17 char answer[MAXSIZE];    //记录答案
 18
 19 int GetHash( int a, int b, int c, int d )
 20 {
 21     return a * 1000 + b * 100 + c * 10 + d;
 22 }
 23
 24 bool check( int x, int y, int dirc, int (*map)[8] )      //判断是否移动成功
 25 {
 26     if ( dirc == 3 && (( map[x][y] >> 3 ) & 1 ))      return false;
 27     if ( dirc == 2 && (( map[x][y] >> 2 ) & 1 ))      return false;
 28     if ( dirc == 1 &&  ( map[x][y] & 1 ) )            return false;
 29     if ( dirc == 0 && (( map[x][y] >> 1 ) & 1 ))      return false;
 30     return true;
 31 }
 32
 33 bool in( int x, int y, int (*map)[8] )       //判断是否越界,是否掉到洞里
 34 {
 35     if ( x >= 1 && x <= 6 && y >= 1 && y <= 6 ) return ( ( map[x][y] >> 4 ) & 1 );
 36     return false;
 37 }
 38
 39 int BFS()
 40 {
 41     //初始化
 42     memset( vis, false, sizeof(vis) );
 43
 44     int front = 0, rear = 0;
 45     int hash = GetHash( start_x1, start_y1, start_x2, start_y2 );
 46     queue[ rear++ ] = hash;   //头结点入队
 47     vis[hash] = true;
 48     fa[hash] = 0;
 49
 50     while ( front < rear )
 51     {
 52         int temp = queue[front];
 53
 54         int x1 = temp / 1000;
 55         int y1 = ( temp / 100 ) % 10;
 56         int x2 = ( temp / 10 ) % 10;
 57         int y2 = temp % 10;
 58
 59         if ( ( ( map1[x1][y1] >> 6 ) & 1 ) && ( ( map2[x2][y2] >> 6 ) & 1 ) ) return temp;   //判断终点
 60
 61         for ( int i = 0; i < 4; i++ )    //四方向移动
 62         {
 63             int xx1 = x1;
 64             int yy1 = y1;
 65
 66             if ( check(xx1, yy1, i, map1) )
 67             {
 68                 xx1 += dx[i];
 69                 yy1 += dy[i];
 70             }
 71
 72             int xx2 = x2;
 73             int yy2 = y2;
 74
 75             if ( check(xx2, yy2, i, map2) )
 76             {
 77                 xx2 += dx[i];
 78                 yy2 += dy[i];
 79             }
 80
 81             if ( !in(xx1, yy1, map1) || !in( xx2, yy2, map2 ) ) continue;
 82
 83             hash = GetHash( xx1, yy1, xx2, yy2 );
 84
 85             if ( !vis[hash] )   //如果该节点尚未访问,插入队列
 86             {
 87                 queue[ rear++ ] = hash;
 88                 fa[hash] = temp;
 89                 dir[hash] = i;
 90                 vis[hash] = true;
 91             }
 92         }
 93         ++front;
 94     }
 95     return -1;      //如果查找失败,返回-1
 96 }
 97
 98 int main()
 99 {
100     int T;
101     scanf( "%d", &T );
102     for ( int i = 1; i <= 6; i++ )
103         for ( int j = 1; j <= 6; j++ )
104         {
105             scanf( "%d", &map2[i][j] );
106             if ( ( map2[i][j] >> 5 ) & 1 )
107             {
108                 start_x2 = i;
109                 start_y2 = j;
110             }
111         }
112
113     --T;
114     while ( T-- )
115     {
116         memcpy( map1, map2, sizeof(map1) );
117         start_x1 = start_x2;
118         start_y1 = start_y2;
119
120         for ( int i = 1; i <= 6; i++ )
121             for ( int j = 1; j <= 6; j++ )
122             {
123                 scanf( "%d", &map2[i][j] );
124                 if ( ( map2[i][j] >> 5 ) & 1 )
125                 {
126                     start_x2 = i;
127                     start_y2 = j;
128                 }
129             }
130
131         int ans = BFS();
132         if ( ans == -1 ) puts("-1");
133         else
134         {
135             int k = -1;
136             for( int i = ans; fa[i] != 0; i = fa[i] )
137                 answer[ ++k ] = move[ dir[i] ];
138
139             for ( ; k >= 0; k-- ) putchar( answer[k] );
140             putchar('\n');
141         }
142     }
143     return 0;
144 }

转载于:https://www.cnblogs.com/GBRgbr/archive/2012/08/05/2623882.html

HDU 3713 Double Maze相关推荐

  1. HDU3713 Double Maze(BFS)

    题目链接: https://cn.vjudge.net/problem/18676/origin Problem Description Unlike single maze, double maze ...

  2. 【HDU - 5094】 Maze (状态压缩+bfs)

    题干: This story happened on the background of Star Trek. Spock, the deputy captain of Starship Enterp ...

  3. HDU 4259 Double Dealing【简单群置换】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4259 题目大意:给出n张卡片以及k个人,现在对卡片进行分堆,然后分发(这样卡片改变了顺序),依次这样问 ...

  4. HDU 1217 Arbitrage (Floyd + SPFA判环)

    题目链接:HDU 1217 Arbitrage 简单的货币转换问题,给定多种货币,以及货币之间的汇率,问能否通过货币的转换实现收益. 例如: 1 US Dollar buys 0.5 British ...

  5. 3kyu Path Finder #3: the Alpinist

    3kyu Path Finder #3: the Alpinist 题目背景: Task You are at start location [0, 0] in mountain area of Nx ...

  6. 4kyu Path Finder #2: shortest path

    4kyu Path Finder #2: shortest path 题目背景: Task You are at position [0, 0] in maze NxN and you can onl ...

  7. 4kyu Path Finder #1: can you reach the exit?

    4kyu Path Finder #1: can you reach the exit? 题目背景: Task You are at position [0, 0] in maze NxN and y ...

  8. POJ - 3565 Ants(二分图最小权匹配+KM+思维)

    题目链接:点击查看 题目大意:给出n个蚂蚁和n个苹果树的坐标,我们需要求出每个蚂蚁平时觅食所要去的苹果树,必须保证所有路径不能有交叉 题目分析:因为所有的边不能有交叉,所以我们选择距离最短的两个点匹配 ...

  9. Gauss高斯消元——模板

    就是线性代数的初等行变化: 倍加. 倍乘. 交换行. #include <bits/stdc++.h> #define mp make_pair #define pb push_backu ...

最新文章

  1. sklearn.naive_bayes
  2. 之一:CABasicAnimation - 基本动画
  3. php session修改时间,PHP如何修改SESSION有效时间?
  4. linux下usb设备节点名不固定,解决Linux下USB设备节点ttyUSB名不固定的问题,生成固定USB转串口设备节点...
  5. [蓝桥杯2017初赛]包子凑数-模拟+巧妙枚举
  6. 厉害了!顶级学术期刊封面的“中国元素”
  7. 传统emmc所用的sdio接口_SolidGear SD/SDIO/eMMC协议分析仪
  8. virtualbox 网络配置
  9. 最新美团JS逆向分析(_token参数)
  10. 目标检测——初始学习率设置的学习笔记
  11. 什么是IEC 61508?
  12. 理解Docker(8):Docker 存储之卷(Volume)
  13. 三星LG纷纷在越南设厂:产能或逐渐从中国转移
  14. python入门神器下载_Python编程神器 v3.7.2 最新免费版
  15. 电力系统计算机辅助分析知乎,电力系统计算机辅助分析
  16. 赚钱鬼才:即使开放外部支付,苹果App Store仍坚持收取佣金
  17. ES6模板字符串中使用变量
  18. 不断收集一些不错的博客(献给未来路上的人)
  19. Java基于springboot+vue+elementUI高速公路收费管理系统设计与实现
  20. CCF:201712-4 行车路线

热门文章

  1. 免费且非常实用的PPT模板网站(免费)亲测可用!!
  2. PhotoShopCS6如何给透明图片填充背景
  3. 2020年,微信的基地属性正在悄然转向
  4. MirSNP:miRNA相关SNP位点数据库
  5. 什么是苹果cms?苹果cms如何安装及使用?
  6. CSS的3D应用:绘制长方体
  7. PTA 7-3 查询水果价格 (15 分)
  8. [百家号]大英帝国的人口和面积比现在的英国大多少?
  9. Python漫画爬虫开源 66漫画 AJAX,包含数据库连接,图片下载处理
  10. 搜狗输入法的符号大全里面可以输入下标