一只甜甜圈
#include <iostream>#include <fstream>using namespace std;struct RZMaze{protected:static int dir[8][2]; //8个方向int n, m, k; //行数、列数、封闭房间数int Romeo[2]; //Romeo所在的位置int Juliet[2]; //Juliet所在的位置int **maze; //迷宫数组int **bestx; //保存最优解int bestc; //保存最优值int dirs; //当前拐弯次数int bccount; //最优解的个数public:RZMaze(int nn, int mm, int kk); //构造函数 //给所有的方格标记~RZMaze(); //析构函数bool InMaze(int x, int y); //判断坐标(x,y)是否还在迷宫内void Backtrack(int dep, int x, int y, int di); //递归回溯 走过多少个字 已经拐了多少弯void ReadData(fstream &fileIn); //从文件中读入数据 //先读封闭房间的行号和列号写入r,cvoid SaveSol(); //保存当前解为最优解void Process(); //处理函数void Output(fstream &fileOut); //将计算结果输出到文件中};//初始化8个方向的偏移量int RZMaze::dir[8][2] = {{-1, 0},{-1,1},{0, 1},{1, 1},{1, 0}, {1, -1}, {0, -1}, {-1, -1}};RZMaze::RZMaze(int nn, int mm, int kk){int i, j;n= nn; m = mm; k = kk;maze = new int* [n];for(i = 0; i < n; i++) maze[i] = new int [m];for(i = 0; i < n; i++){for(j = 0; j < m; j++) maze[i][j] = 0;}bestx = new int* [n];for(i = 0; i < n; i++) bestx[i] = new int [m];for(i = 0; i < n; i++){for(j = 0; j < m; j++) bestx[i][j] = 0;}}RZMaze::~RZMaze(){int i;for(i = 0; i < n; i++) delete [] maze[i];delete maze;for(i = 0; i < n; i++) delete [] bestx[i];delete bestx;}void RZMaze::SaveSol(){int i, j;for(i = 0; i < n; i++){for(j = 0; j < m; j++) bestx[i][j] = maze[i][j];}}bool RZMaze::InMaze(int x, int y){return x >= 0 && x < n && y >= 0 && y< m;}//递归回溯函数,dep表示已经走过了多少个方格,(x,y)为当前坐标,di为已经拐弯的次数void RZMaze::Backtrack(int dep, int x, inty, int di){int i; int p, q; int tmp;if(dep == m * n - k && x == Juliet[0] && y == Juliet[1])//找到一个解{if(dirs < bestc){bestc = dirs; //更新最优值bccount = 1; //找到第一个最优解SaveSol(); //更新最优解}else if(dirs == bestc){bccount++; //最优解个数加1}return;}if(dirs > bestc) return; //找不到更好的解 剪枝else{for(i = 0; i < 8; i++) //8个方向逐一试探{p = x + dir[i][0]; q = y + dir[i][1]; //计算下一个位置if(!InMaze(p, q) || maze[p][q] != 0) //不在迷宫内或者以前来过或者封闭房间{continue;}tmp = maze[p][q];maze[p][q] = dep + 1; //下一个走到的位置if(dep > 1 && di != i) dirs++; //拐弯(第一次探路不算拐弯)Backtrack(dep + 1, p, q, i); //递归if(dep > 1 && di != i) dirs--; //撤销maze[p][q] = tmp;}}}void RZMaze::Process(){bccount = 0; bestc = n * m; dirs = 0;maze[Romeo[0]][Romeo[1]] = 1;Backtrack(1, Romeo[0], Romeo[1], 0);}void RZMaze::ReadData(fstream &fileIn){int i; int r, c;for(i = 0; i < k; i++){fileIn >> r >> c;maze[r - 1][c - 1] = -1; //把封闭房间标记-1}fileIn >> r >> c;Romeo[0] = r - 1; Romeo[1] = c - 1;fileIn>>r>>c;Juliet[0] = r - 1; Juliet[1] = c - 1;}void RZMaze::Output(fstream &fileOut){int i, j;if(bccount == 0){cout << "No Solution\n";fileOut << "No Solution\n";return;}cout << bestc << '\n' << bccount << '\n';fileOut << bestc << '\n' << bccount << '\n';for(i = 0; i < n; i++){for(j = 0; j < m; j++){cout << bestx[i][j] << '\t';fileOut << bestx[i][j] << '\t';}cout << '\n';fileOut << '\n';}}int main(){int n, m, k;fstream fileIn, fileOut;fileIn.open("in.txt", ios::in);fileOut.open("out.txt", ios::out);if(!fileIn){cout<<"文件打开错误!"<<endl;return 0;}fileIn >> n >> m >> k;RZMaze r(n, m, k);r.ReadData(fileIn);r.Process();r.Output(fileOut);return 0;}