| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
单向BFS + 备忘录 + 一个限界条件 = AC#pragma warning(disable: 4786)
#include <iostream>
#include <queue>
using namespace std;
// 养成定义宏或const的习惯 方便测试
#define PWDLEN 6
#define STATECODELEN (PWDLEN + 3) * 4
// 注意这里枚举的顺序 把Up和Down放在一起 方便下面的优化
enum Key {Swap0 = 0, Swap1, Up, Down, Left, Right};
// vc中有__int64可用 G++编译不能通过
class State
{
public:
State(const char *a, int index);
State(__int64 stateCode);
bool Press(Key key);
__int64 StateCode();
int MemoCode();
char Depth();
bool IsInThis(char n);
bool IsInPos(const State &s);
char PointedTo();
bool operator == (const State &rhs);
protected:
typedef bool (State::*Manipulation)();
bool PressSwap0();
bool PressSwap1();
bool PressUp();
bool PressDown();
bool PressLeft();
bool PressRight();
void Change();
void Init();
void Reset2Code();
private:
char _a[PWDLEN];
// 特别注意stateCode是按位操作生成的 借助__int64提高效率
__int64 _stateCode;
int _memoCode;
bool _isChanged;
char _index;
char _depth;
Manipulation _mani[6];
};
class Seacher
{
public:
Seacher(const char *begin, const char *end);
~Seacher();
int Search();
protected:
int BFS();
private:
State _begin, _end;
bool *_memo;
};
int main()
{
char begin[PWDLEN + 1], end[PWDLEN + 1];
cin >> begin >> end;
Seacher s(begin, end);
cout << s.Search() << endl;
return 0;
}
State::State(const char *a = NULL, int index = 0)
: _stateCode(0), _isChanged(true), _index(index), _depth(0)
{
Init();
if (a)
{
for (int i = 0; i < PWDLEN; ++i)
{
_a[i] = a[i] - '0';
}
}
}
State::State(__int64 stateCode)
: _stateCode(0), _isChanged(true), _index(0), _depth(0)
{
Init();
__int64 temp;
temp = stateCode & __int64(0xff);
_depth = temp;
stateCode >>= 8;
temp = stateCode & __int64(0xf);
_index = temp;
stateCode >>= 4;
for (int i = PWDLEN - 1; i >= 0; --i)
{
temp = stateCode & __int64(0xf);
_a[i] = temp;
stateCode >>= 4;
}
}
void State::Init()
{
memset(_a, 0, (PWDLEN + 1) * sizeof(char));
_mani[Swap0] = &State::PressSwap0;
_mani[Swap1] = &State::PressSwap1;
_mani[Up] = &State::PressUp;
_mani[Down] = &State::PressDown;
_mani[Left] = &State::PressLeft;
_mani[Right] = &State::PressRight;
}
bool State::Press(Key key)
{
// 注意this->*的写法
return (this->*_mani[key])();
}
inline void State::Reset2Code()
{
int i, x;
_memoCode = _index;
for (i = 0, x = 10; i < PWDLEN; ++i)
{
_memoCode += (_a[PWDLEN - 1 - i]) * x;
x *= 10;
}
_stateCode = 0;
for (i = 0; i < PWDLEN; ++i)
{
_stateCode |= _a[i];
_stateCode <<= 4;
}
_stateCode |= _index;
_stateCode <<= 8;
_stateCode |= _depth;
}
inline int State::MemoCode()
{
if (_isChanged)
{
Reset2Code();
_isChanged = false;
}
return _memoCode;
}
inline __int64 State::StateCode()
{
if (_isChanged)
{
Reset2Code();
_isChanged = false;
}
return _stateCode;
}
inline char State::Depth()
{
return _depth;
}
// 用一个函数将_isChanged和_depth
inline void State::Change()
{
_isChanged = true;
++_depth;
}
inline bool State::IsInThis(char n)
{
for (int i = 0; i < PWDLEN; ++i)
{
if (_a[i] == n)
{
return true;
}
}
return false;
}
inline bool State::IsInPos(const State &s)
{
return _a[_index] == s._a[s._index];
}
inline char State::PointedTo()
{
return _a[_index];
}
bool State::PressSwap0()
{
if (!_index)
{
return false;
}
char temp = _a[_index];
_a[_index] = _a[0];
_a[0] = temp;
Change();
return true;
}
bool State::PressSwap1()
{
if (PWDLEN - 1 == _index)
{
return false;
}
char temp = _a[_index];
_a[_index] = _a[PWDLEN - 1];
_a[PWDLEN - 1] = temp;
Change();
return true;
}
bool State::PressUp()
{
if (9 == _a[_index])
{
return false;
}
++_a[_index];
Change();
return true;
}
bool State::PressDown()
{
if (!_a[_index])
{
return false;
}
--_a[_index];
Change();
return true;
}
bool State::PressLeft()
{
if (!_index)
{
return false;
}
--_index;
Change();
return true;
}
bool State::PressRight()
{
if (PWDLEN - 1 == _index)
{
return false;
}
++_index;
Change();
return true;
}
bool State::operator == (const State &rhs)
{
return !memcmp(_a, rhs._a, PWDLEN * sizeof(char));
}
Seacher::Seacher(const char *begin, const char *end)
: _begin(begin), _end(end), _memo(NULL)
{
int memoLen = 1;
for (int i = 0; i < PWDLEN + 1; ++i)
{
memoLen *= 10;
}
_memo = new bool[memoLen];
memset(_memo, 0, memoLen * sizeof(bool));
}
Seacher::~Seacher()
{
delete _memo;
_memo = NULL;
}
inline int Seacher::Search()
{
return BFS();
}
int Seacher::BFS()
{
_memo[_begin.MemoCode()] = true;
queue<__int64> q;
q.push(_begin.StateCode());
while (!q.empty())
{
State now = q.front();
if (now == _end)
{
return now.Depth();
}
q.pop();
int fbegin = Swap0;
int fend = Right;
// 这里表示如果当年指向的点的数没有出现在end中 那么一定要是其成为end的其中一个数
if (!_end.IsInThis(now.PointedTo()))
{
fbegin = Up;
fend = Down;
}
// 注意这里不能加 不能认为当前位置满足要求就不变 考虑swap
// if (_end.IsInPos(now))
// {
// fbegin = Left;
// fend = Right;
// }
// else if (!_end.IsInThis(now.PointedTo()))
// {
// fbegin = Up;
// fend = Down;
// }
for (int key = fbegin; key <= fend; ++key)
{
State temp = now;
if (temp.Press(Key(key)) && !_memo[temp.MemoCode()])
{
_memo[temp.MemoCode()] = true;
q.push(temp.StateCode());
}
}
}
return 0;
}
Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator