HDU - 3023 Dirt

来源:互联网 发布:手机淘宝能收藏店铺吗 编辑:程序博客网 时间:2024/06/14 06:45
Dirt
Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u

Submit Status

Description

-- Hello, may I speak to Petrov, please? Hello, my darling... You know, there was a little accident at our home... No, no, don't worry, your computer was not damaged. It is only a bit dirty there now. Well, I should say it's very dirty there and I'm at my Mom's now. Of course, I'll clean it... When? Well, maybe when I have my vacation. What? Well, when we are back from Turkey... the next vacation then. I'll stay at Mother's until then, and you may live here also. No, no, I don't insist, sure, you may stay at home if you wish so. I prepared boots for you, they are at the door. But please, don't make it worse, before you step on a clean floor, change your boots, put on your slippers, they are at the door also. Take them with you when you walk through the dirt. And when you walk on a clean floor, take the boots with you. You see, the dirt is in different places. OK, my love? Thank you! 

It is not a great pleasure to change boots each time you get from a clean floor to a dirty floor and vice versa, it's easier to walk extra several meters. So it is necessary to find a way of getting from one place in the apartment to another with the minimal possible number of boots changes; and among these paths the shortest one must be found. 

To begin with, it is natural to determine an optimal way of passing the Most Important Route: from the computer to the refrigerator.
 

Input

The first line of the input contains two integers M and N, which are dimensions of the apartment (in meters), 1 ≤ N, M ≤ 1000. The two integers in the second line are the coordinates of the computer, and the third line contains the coordinates of the refrigerator. Each of the following M lines contains N symbols; this is the plan of the apartment. On the plan, 1 denotes a clean square, 2 denotes a dirty square, and 0 is either a wall or a square of impassable dirt. It is possible to get from one square to another if they have a common vertex. When you pass from a clean square to a dirty one or vice versa, you must change shoes. The computer and the refrigerator are not on the squares marked with 0. 

The upper left square of the plan has coordinates (1, 1).
 

Output

You should output two integers in one line separated with a space. The first integer is the length of the shortest path (the number of squares on this path including the first and the last squares) with the minimal possible number of boots changes. The second number is the number of boots changes. If it is impossible to get from the computer to the refrigerator, you should output 0 0.
 

Sample Input

3 71 13 7120012112120201112021
 

Sample Output

8 4
 

#include<iostream>#include<cstring>#include<cstdio>#include<queue>#define N 1001using namespace std;int fx[8][2] = { 0, 1, 0, -1, 1, 0, -1, 0, 1, 1, 1, -1, -1, 1, -1, -1 }, n, m, sx, sy, ex, ey, tp, tb;  //八个方向都可走struct Map{int cb;int path;int x;int y;char c;friend   bool operator<(Map t1, Map t2)   //定义结构体的比较,换鞋次数优先,步数其次{if (t1.cb == t2.cb){return t1.path>t2.path;}return t1.cb>t2.cb;}};Map map[N][N];void input(){int i, j, k;scanf("%d%d%d%d", &sx, &sy, &ex, &ey);   //起点终点的坐标for (i = 1; i <= n; i++)                 //地图{getchar();for (j = 1; j <= m; j++){map[i][j].c = getchar();map[i][j].path = -1;            //地图上各个点初始化为-1}}}bool isvalide(int x, int y)         //判断是否合法{if (x<1 || x>n || y<1 || y>m || map[x][y].c == '0')  return false;return true;}void BFS(){int i, j, k;priority_queue<Map> qu;Map t1, t2;int tx, ty;map[sx][sy].path = 0;        //起点map[sx][sy].cb = 0;t1 = map[sx][sy];t1.x = sx;t1.y = sy;qu.push(t1);while (!qu.empty()){t2 = qu.top();if (t2.cb>tb || (t2.cb == tb&&t2.path >= tp))        //取出的点数据大于最优解,退出???还是不太明白为什么这样??return;qu.pop();for (i = 0; i<8; i++){tx = t2.x + fx[i][0];            //试探八个方向ty = t2.y + fx[i][1];if (isvalide(tx, ty)){if (map[tx][ty].path != -1)         //已经搜索过{if (map[tx][ty].c != t2.c)      //符号不同,需要换鞋{if (map[tx][ty].cb<t2.cb + 1 || (map[tx][ty].cb == t2.cb + 1 && map[tx][ty].path <= t2.path + 1))continue;                              //按上面路程走到这里的cb path大于原来的,不改变该点的数据map[tx][ty].cb = t2.cb + 1;                //否则,改变map[tx][ty].path = t2.path + 1;}else                            //符号相同,不需换鞋{if (map[tx][ty].cb<t2.cb || (map[tx][ty].cb == t2.cb&&map[tx][ty].path <= t2.path + 1))  continue;                   //新的cb path比原来的大,不改变原数据map[tx][ty].cb = t2.cb;         //否则改变map[tx][ty].path = t2.path + 1;}}else   //未搜索过的{if (map[tx][ty].c != t2.c)        //符号不同,换鞋,cb++{map[tx][ty].cb = t2.cb + 1;map[tx][ty].path = t2.path + 1;}else                              //符号相同,只改变步数{map[tx][ty].cb = t2.cb;map[tx][ty].path = t2.path + 1;}}t1 = map[tx][ty];t1.x = tx;t1.y = ty;if (tx == ex&&ey == ty)         //到达终点,更新其数据tb,tp{if (t1.cb<tb){tb = t1.cb;tp = t1.path;}else if (t1.cb == tb&&t1.path<tp){tp = t1.path;}continue;}qu.push(t1);      //合法的位置压入栈}}}}int main(){while (scanf("%d%d", &n, &m) != EOF){input();tb = tp = 100000;        //tb tp记录最优解的换鞋次数和步数BFS();printf("%d %d\n", tp + 1, tb);}}


0 0