#include<iostream>
#include<fstream>
using namespace std;
const int MAX = 10;
int n, m, k;
int board[MAX][MAX];
int best[MAX][MAX];
int dirs = 0; //转弯次数
int min = 100000; //最少转弯次数
int count = 0; //不同的最少转弯道路数
struct Point
{
int x, y;
};
Point luo;
Point ye;
int dx[8] = {1, 0, -1, 0, 1, 1, -1, -1}; //八个方向
int dy[8] = {0, 1, 0, -1, 1, -1, 1, -1};
bool ok(int x, int y)
{
if(x>0 && y>0 && x<=n && y<=m && board[x][y]==0) //在迷宫内且未走到封闭房间
return true;
else
return false;
}
void save()
{
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
best[i][j] = board[i][j];
}
void backtrack(int x, int y, int dep, int di)
{
if(dep == n*m-k && x == ye.x && y == ye.y && dirs<=min)
{ //如果所有方格走遍,且到达朱丽叶位置,且转弯次数<=最优转弯次数
if(dirs < min) //如果<最优转弯次数
{
min = dirs;
count = 1; //重新记录道路数
save();
}
else
count++; //否则道路数增加
return;
}
if(dep == n*m-k && x == ye.x && y == ye.y && dirs>min)
return;
for(int i=0; i<8; i++) //可走的八个方向
{
int nextx = x + dx[i]; //计算下一步坐标
int nexty = y + dy[i];
if(ok(nextx, nexty)) //如果下一步可行
{
board[nextx][nexty] = dep + 1;
if(dep>1 && di != i) //第一步不算转弯,如果方向不同,转弯次数增加
dirs++;
backtrack(nextx, nexty, dep+1, i);
board[nextx][nexty] = 0; //回溯
if(dep>1 && di != i)
dirs--;
}
}
}
int main()
{
ifstream fin("罗密欧.txt");
cout << "\n输入行数n:";
fin >> n; cout << n;
cout << "\n输入列数m:";
fin >> m; cout << m;
cout << "\n输入封闭的房间数:";
fin >> k; cout << k << endl;
int i;
memset(board, 0, sizeof(board));
int x, y;
for(i=1; i<=k; i++)
{
cout << "输入第" << i << "个封闭房间所在的行号和列号:";
fin >> x >> y;
cout << x << " " << y << endl;
board[x][y] = -1; //标记封闭房间
}
cout << "输入罗密欧位置:";
fin >> luo.x >> luo.y;
cout << luo.x << " " << luo.y;
cout << "\n输入朱丽叶位置:";
fin >> ye.x >> ye.y;
cout << ye.x << " " << ye.y;
board[ luo.x ][ luo.y ] = 1;
backtrack(luo.x, luo.y, 1, 0);
cout << "\n最少转弯次数为:" << min;
cout << "\n不同的最少转弯道路数为:" << count;
cout << "\n一条路径为:\n";
for(i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
cout << best[i][j] << "\t";
cout << endl;
}
cout << endl << endl;
return 0;
}
罗密欧与朱丽叶迷宫问题
最新推荐文章于 2024-05-03 19:43:37 发布