修改案例分析的程序,输出不带有死胡同但是可以带迂回路(可能的话)的路径

修改案例分析的程序,输出不带有死胡同但是可以带迂回路(可能的话)的路径。例如,对一个输入的迷宫:

在这里插入图片描述

案例分析的程序输出了经过处理后的迷宫图:

在这里插入图片描述

修改后的程序应该产生从出口到老鼠初始位置的路径:
[1 1] [1 2] [1 3] [2 3] [3 3] [3 4] [3 5] [4 5] [4 4] [4 3]
它删除了两个死胡同:[1 4][1 5]和[3 2][3 1][4 1][4 2],但是保留了迂回路径:[3 4][3 5] [4 5][4 4]

分析:我们注意经过处理后的迷宫图,结合之前的案例分析,我们知道此次修改并未涉及到mazeStack栈,因为人还是照例走了一遍全程。那么题目的意思即为:并不管你是否走没走死胡同,但是修改后的程序输出路径时不能允许死胡同路段。综上,咱们可以先保存所有的路径点,在想办法判断出所有路径点中死胡同,删除即可。这里判断是否为死胡同时,我们需要知道回溯点以及死胡同点,两者之间的路径则为死胡同点。
预期结果如下图所示

在这里插入图片描述
参考代码如下(只用修改exitMaze)

void Maze::exitMaze() {
 int cds = 0; //判断死胡同点标志位
 int row, col, i=0;
 vector<Cell> c1, c2, c3;
 currentCell = entryCell;
 c1.push_back(entryCell);
 while (!(currentCell==exitCell))
 {
  row = currentCell.x;
  col = currentCell.y;
  cout << *this;
  if (!(currentCell == entryCell))
   store[row][col] = visited;
  pushUnvisited(row - 1, col);
  pushUnvisited(row + 1, col);
  pushUnvisited(row, col - 1);
  pushUnvisited(row, col + 1);
  if (!((mazeStack.top() == Cell(row - 1, col)) ||(mazeStack.top() == Cell(row + 1, col)) || (mazeStack.top() == Cell(row, col - 1)) || (mazeStack.top() == Cell(row, col + 1))))
  {
   //cout << "死胡同"<<endl ;
   cds = 1; //死胡同点,标志位置1
  }
  if (cds)
  {
   c2.push_back(currentCell); //将死胡同点压入c2栈内,等待后续处理
   cds = 0; //一旦压入,立即清0,等待下一个死胡同点
  }
  if (mazeStack.empty())
  {
   cout << *this;
   cout << "Failure\n";
   return;
  }
  else currentCell = mazeStack.pop();
  c1.push_back(currentCell); //将路径经过的所有点压入c1栈内
; }
 cout << *this;
 //输出所有路径点
 cout << "所有路径点:";
 for (int j = 0; j < c1.size(); j++)
 {
  cout << '[' << c1[j].x << ','
   << c1[j].y << ']' << ' ' ;
 }
 cout << endl;
 c2.erase(unique(c2.begin(),c2.end()),c2.end()); //清楚重复死胡同点
 //输出死胡同点
 cout << "死胡同点:";
 for (int k = 0; k < c2.size(); k++)
 {
  cout << '[' << c2[k].x << ','
   << c2[k].y << ']' << ' ' ;
 }
 //找到回溯点,压入c3栈内
 for (int i = 0; i < c2.size(); i++)
 {
  for (int j = 0; j < c1.size(); j++)
  {
   if (c2[i]==c1[j]&&!(c2[i]==c1[j+1]))
   {
    c3.push_back(c1[j+1]);
   }
  }
 }
 cout << endl;
 //输出回溯点
 cout << "回溯点:";
 for (int k = 0; k < c3.size(); k++)
 {
  cout << '[' << c3[k].x << ','
   << c3[k].y << ']' << ' ';
 }
 vector<int> k1;
 //找到死胡同点在栈c1中的位置
 for (int i = 0; i < c2.size(); i++)
 {
  for (int j = 0; j < c1.size(); j++)
  {
   if (c2[i] == c1[j])
   {
    k1.push_back(j);
   }
  }
 }
 //删除路径中的死胡同点
 for (int i = 0; i < k1.size(); i++)
 {
  c1.erase(c1.begin() + k1[i]-i);
 }
 cout << endl;
 //删除死胡同的其余各点
 int k2, k3;
 for (int i = 0; i < c3.size(); i++)
 {
  for (int j = 0; j < c1.size(); j++)
  {
   if (((c1[j].x == (c3[i].x) + 1) && c1[j].y == c3[i].y) || ((c1[j].x == (c3[i].x) - 1) && c1[j].y == c3[i].y)
    || ((c1[j].y == (c3[i].y) + 1) && c1[j].x == c3[i].x) || ((c1[j].y == (c3[i].y) - 1) && c1[j].x == c3[i].x))
   {
    k2 = j;
    for (int k = k2; k < c1.size(); k++)
    {
     if (c1[k]==c3[i])
     {
      k3 = k; break;
     }
     else k3 = -1;
    }
    if (k3>k2)
    {
     c1.erase(c1.begin() + k2 + 1, c1.begin() + k3);
    }
   }
  }
 }
 cout << "带有迂回路,不带死胡同的路径点:";
 for (int j = 0; j < c1.size(); j++)
 {
  cout << '[' << c1[j].x << ','
   << c1[j].y << ']' << ' ';
 }
 cout << endl << "Success\n";
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值