具体题目有些忘了。题目大意是这样的,一个tank从A点出发,到目的地B,只能“+”“-“交叉走,走过的位置不能再走。求最短步数。典型BFS题目。用C++做相对要简单一些,毕竟有STL…
Tank.h
/*迷宫栗子图,建立txt文本,放在E盘下
* A + - + - *
* + - + - + *
* - + - + - *
* - + + + - *
* B + - + + *
*/
#ifndef TANK_H_
#define TANK_H_ 1
#include
#include
#include
using std::queue;
using std::vector;
enum Dire {Left = 0, Down, Right, Up, None};
struct Node
{
int _cur;
Dire _dire; //之前的方向
};
class Tank
{
private:
queue<vector > pos;
public:
Tank(const char** tank_map, int n); // tank_map为存入地图
~Tank();
//test
public:
//void get_all() const;
int get_step() const; //返回步数
bool trace(); // 驱动
private:
bool finish() const; // 判断是否走到目的点
bool can_move_left() const;
bool can_move_down() const;
bool can_move_right() const;
bool can_move_up() const;
void get_pos();
private:
bool** _map_had_move; //已经走过
bool** _map_plus_minus; //正-true,负-false
const char** _map; // 指向地图
int _start; // 开始位置
int _cur; // 当前位置
int _end; // 目的位置
bool _move; // 当前位置的正负
Dire _drec; // 当前方向
int _N; // N * N数组大小
int _step; // 记录步数
};
#endif // TANK_H_
Tank.cpp
#include "tank.h"
#include
Tank::Tank(const char** tank_map, int n)
{
_N = n;
_map = tank_map;
get_pos();
_move = true;
_step = 0;
_drec = None;
Node tmp;
tmp._cur = _cur;
tmp._dire = None;
vector t;
t.push_back(tmp);
pos.push(t);
_map_had_move = new bool* [_N];
for (int i = 0; i < _N; ++i)
_map_had_move[i] = new bool [_N];
for (int i = 0; i < _N; ++i)
for (int j = 0; j < _N; ++j)
_map_had_move[i][j] = false;
_map_had_move[_start/_N][_start%_N] = true; //标记起点已走
}
Tank::~Tank()
{
for (int i = 0; i < _N; ++i)
{
delete [] _map_had_move[i];
delete [] _map_plus_minus[i];
}
}
inline bool Tank::finish() const
{
return _cur == _end;
}
bool Tank::can_move_left() const
{
if ((_drec == None || Left != _drec) && _cur%_N-1 >= 0 && (_map[_cur/_N][_cur%_N-1] == 'A' || _map[_cur/_N][_cur%_N-1] == 'B'))
return true;
if ((_drec == None || Left != _drec) && _cur%_N-1 >= 0 && !_map_had_move[_cur/_N][_cur%_N-1])
{
if (_map[_cur/_N][_cur%_N] == 'A' || _map[_cur/_N][_cur%_N] == 'B')
return true;
else
return _map_plus_minus[_cur/_N][_cur%_N-1] ^ _map_plus_minus[_cur/_N][_cur%_N];
}
return false;
}
bool Tank::can_move_down() const
{
if ((_drec == None || Down != _drec) && _cur/_N+1 < _N && (_map[_cur/_N+1][_cur%_N] == 'A' || _map[_cur/_N+1][_cur%_N] == 'B'))
return true;
if ((_drec == None || Down != _drec) && _cur/_N+1 < _N && !_map_had_move[_cur/_N+1][_cur%_N])
{
if (_map[_cur/_N][_cur%_N] == 'A' || _map[_cur/_N][_cur%_N] == 'B')
return true;
else
return _map_plus_minus[_cur/_N+1][_cur%_N] ^ _map_plus_minus[_cur/_N][_cur%_N];
}
return false;
}
bool Tank::can_move_right() const
{
if ((_drec == None || Right != _drec) && _cur%_N+1 < _N && (_map[_cur/_N][_cur%_N+1] == 'A' || _map[_cur/_N][_cur%_N+1] == 'B'))
return true;
if ((_drec == None || Right != _drec) && _cur%_N+1 < _N && !_map_had_move[_cur/_N][_cur%_N+1])
{
if (_map[_cur/_N][_cur%_N] == 'A' || _map[_cur/_N][_cur%_N] == 'B')
return true;
else
return _map_plus_minus[_cur/_N][_cur%_N+1] ^ _map_plus_minus[_cur/_N][_cur%_N];
}
return false;
}
bool Tank::can_move_up() const
{
if ((_drec == None || Up != _drec) && _cur/_N-1 >= 0 && (_map[_cur/_N-1][_cur%_N] == 'A' || _map[_cur/_N-1][_cur%_N] == 'B'))
return true;
if ((_drec == None || Up != _drec) && _cur/_N-1 >= 0 && !_map_had_move[_cur/_N-1][_cur%_N])
{
if (_map[_cur/_N][_cur%_N] == 'A' || _map[_cur/_N][_cur%_N] == 'B')
return true;
else
return _map_plus_minus[_cur/_N-1][_cur%_N] ^ _map_plus_minus[_cur/_N][_cur%_N];
}
return false;
}
void Tank::get_pos()
{
_map_plus_minus = new bool* [_N];
for (int i = 0; i < _N; ++i)
_map_plus_minus[i] = new bool [_N];
for (int i = 0; i < _N * _N; ++i)
{
if (_map[i/_N][i%_N] == 'A')
{
_cur = _start = i;
_map_plus_minus[i/_N][i%_N] = true;
}
if (_map[i/_N][i%_N] == 'B')
{
_end = i;
_map_plus_minus[i/_N][i%_N] = true;
}
if (_map[i/_N][i%_N] == '+')
_map_plus_minus[i/_N][i%_N] = true;
if (_map[i/_N][i%_N] == '-')
_map_plus_minus[i/_N][i%_N] = false;
}
}
bool Tank::trace()
{
while (!pos.empty())
{
vector tmp = pos.front();
pos.pop();
vector ::iterator iter = tmp.begin();
vector push_to_pos;
while(iter != tmp.end())
{
Node t = *iter;
_cur = t._cur;
_drec = t._dire;
if (finish()) //判断是否到达了目的地
return true;
if (can_move_left())
{
t._cur = _cur - 1;
t._dire = Right;
push_to_pos.push_back(t);
_map_had_move[t._cur/_N][t._cur%_N] = true;
}
if (can_move_down())
{
t._cur = _cur + _N;
t._dire = Up;
push_to_pos.push_back(t);
_map_had_move[t._cur/_N][t._cur%_N] = true;
}
if (can_move_right())
{
t._cur = _cur + 1;
t._dire = Left;
push_to_pos.push_back(t);
_map_had_move[t._cur/_N][t._cur%_N] = true;
}
if (can_move_up())
{
t._cur = _cur - _N;
t._dire = Down;
push_to_pos.push_back(t);
_map_had_move[t._cur/_N][t._cur%_N] = true;
}
iter++;
//输出轨迹
/*std::cout << "t._cur: " << t._cur << "t._dire: " << t._dire << std::endl;
for (int i = 0; i < _N; ++i)
for (int j = 0; j < _N; ++j)
{
std::cout << _map_had_move[i][j] << " ";
if (j == _N - 1)
std::cout << std::endl;
}*/
}
if (!push_to_pos.empty())
pos.push(push_to_pos);
++_step;
}
return false;
}
int Tank::get_step() const
{
return _step;
}
main.cpp
#include "tank.h"
#include
int main()
{
using std::ifstream;
using std::cout;
using std::endl;
ifstream read_file("E:\\test.txt");
if(read_file.is_open())
{
int n;
read_file >> n;
char** tank_map;
tank_map = new char* [n];
for (int i = 0; i < n; ++i)
tank_map[i] = new char [n];
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
read_file >> tank_map[i][j];
Tank tank((const char**)tank_map, n);
if (tank.trace())
cout << "step: " << tank.get_step() << endl;
else
cout << -1 << endl;
}
return 0;
}
当时没做出来,后来想想才做出来(泪。。)