有一個4*2的方框,裏面隨機填充着0-7這8個數。每次只有0可以交換相鄰格子裏的數。比如:
可以交換爲
或者
最終結果
思路:與前幾題的bfs不同,這次的bfs沒有明確的移動對象,看似任意一個數都可以當成對象移動。把0作爲移動對象,那麼0在地圖中漫遊所有的格子得到的肯定就是問題的解空間。由於題目的輸入是多個case,如果對每個case都運行一遍bfs就會TLE。這時我們祭出dp技能,只需要一次bfs就將解空間算出來,以後每個case只要到解空間中去找就行了。
#include <iostream>
#include <string>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;
map<string, int> dp;
int direction[4] = { 1, -1, 4, -4 };
//************************************
// Method: bfs
// FullName: bfs
// Access: public
// Returns: void
// Qualifier: 讓0漫遊整個字串
//************************************
void bfs()
{
queue<string> que;
que.push("01234567");
dp["01234567"] = 0;
while (!que.empty())
{
string now = que.front(); que.pop();
// p是'0'的位置
int p = 0;
for (int j = 0; j < 8; ++j)
{
if (now[j] == '0')
{
p = j;
break;
}
}
for (int i = 0; i < 4; ++i)
{
int n = p + direction[i];
if (0 <= n && n < 8 &&
!(p == 3 && i == 0) && // 右上角不能再往右了
!(p == 4 && i == 1)) // 左下角不能再往左了
{
string next = now;
swap(next[p], next[n]);
if (dp.find(next) == dp.end())
{
dp[next] = dp[now] + 1;
que.push(next);
}
}
}
}
}
///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{
bfs();
string line;
while (getline(cin, line))
{
line.erase(remove(line.begin(), line.end(), ' '), line.end());
cout << dp[line] << endl;
}
return 0;
}
///////////////////////////End Sub//////////////////////////////////
代碼格式挺好的,值得學習。(廣度搜索我太垃圾了- -)