Tank走迷宫(某比赛决赛题)

来源:互联网 发布:手机淘宝客户端是什么 编辑:程序博客网 时间:2024/04/27 23:22

具体题目有些忘了。题目大意是这样的,一个tank从A点出发,到目的地B,只能“+”“-“交叉走,走过的位置不能再走。求最短步数。典型BFS题目。用C++做相对要简单一些,毕竟有STL…

Tank.h

/*迷宫栗子图,建立txt文本,放在E盘下 * A + - + - * * + - + - + * * - + - + - * * - + + + - * * B + - + + **/#ifndef TANK_H_#define TANK_H_ 1#include <queue>#include <vector>#include <iostream>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<Node> > pos;public:    Tank(const char** tank_map, int n);        // tank_map为存入地图    ~Tank();    //testpublic:    //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 <iostream>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<Node> 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<Node> tmp = pos.front();        pos.pop();        vector<Node>::iterator iter = tmp.begin();        vector<Node> 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 <fstream>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;}

当时没做出来,后来想想才做出来(泪。。)

0 0
原创粉丝点击