修改案例分析的程序,输出不带有死胡同但是可以带迂回路(可能的话)的路径。例如,对一个输入的迷宫:
案例分析的程序输出了经过处理后的迷宫图:
修改后的程序应该产生从出口到老鼠初始位置的路径:
[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";
}