tjut 3023

来源:互联网 发布:超市毛利率算法 编辑:程序博客网 时间:2024/06/01 09:15
#include<iostream>  #include<cstring>  #include<cstdio>  #include<queue>  #define N 1001  using 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