這題的意思是給你一個8個方格的矩形,裏面有0~7這八個數字,規定只能移動0這個方格和相鄰的方格對調,現在給你一種雜亂的情況,問你最少經過多少步才能恢復成0到7按行和列的順序排列。
挺有意思的,從來沒做過這種思路的題,就是先從結果(排好序)的情況出發,bfs遍歷所有移動0可能變成的情況,最短路徑用map<string, int>存,然後對每個詢問一一輸出就好了。
#include <bits/stdc++.h>
using namespace std;
int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
vector<int> op(20);
map<string, int> dis;
struct node {
string s;
int x, y, step;
node() {}
node(string _s, int _x, int _y, int _step) : s(_s), x(_x), y(_y), step(_step) {}
};
int input(){
string str, ss;
getline(cin, str);
if (str[0] == '-')
return -1;
istringstream s(str);
vector<int> v;
v.clear();
while(s >> ss){
int tmp = 0;
for (int i = 0;i < int(ss.size()); i++)
tmp = tmp * 10 + (ss[i] - '0');
v.push_back(tmp);
}
for (int i = 0;i < int(v.size()); i++)
op[i] = v[i];
return v.size();
}
void bfs() {
queue<node> q;
q.push(node("01234567", 0, 0, 0));
dis["01234567"] = 0;
while (!q.empty()) {
node now = q.front();
q.pop();
string temp;
for (int i = 0; i < 4; ++i) {
int tx = now.x + dir[i][0];
int ty = now.y + dir[i][1];
if (tx < 0 || tx > 1 || ty < 0 || ty > 3) continue;
temp = now.s;
swap(temp[tx * 4 + ty], temp[now.x * 4 + now.y]);
if (!dis[temp] && temp != "01234567") {
dis[temp] = now.step + 1;
q.push(node(temp, tx, ty, now.step + 1));
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.precision(10);
cout << fixed;
#ifdef LOCAL_DEFINE
freopen("input.txt", "r", stdin);
#endif
bfs();
while (input()) {
string res = "";
for (int i = 0; i < 8; ++i) {
res += char(int('0') + op[i]);
}
cout << dis[res] << '\n';
}
#ifdef LOCAL_DEFINE
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}