最简单,最low的bfs暴力,凑合着看看吧
/*对有解性证明。
引理:一个排列中任意两个元素对换,排列改变奇偶性
设初始状态x1x2x3x4[]x5x6x7x8 ([]为空格)
[]有4种移动方式
1.当[]左右移动,其排列相对次序不变,排列奇偶性不改变
2.当[]上下移动,先考虑向下移动,初始状态改变为x1x2x3x4x7x5x6x8,相当于进行了2次相邻对换,排列奇偶性不变。向上同理。
即证:不论如何移动,初始状态与目标状态的排列奇偶性应当一致,不然无解。
*/
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<ctime>
#include <unordered_map>
using namespace std;
string s0, sg;
int Is_odd(string s) {//排列的奇偶性
int cnt = 0;
for (int i = 0;i < s.length();++i) {//反正数据量小 O(n^2)怕啥。那不成还写归并排序吗。。我也不会呀
for (int j = i + 1;j < s.length();++j) {
if (s[i] != '0' && s[j] != '0' && s[i] - s[j] > 0) cnt++;
}
}
return cnt % 2;//1
}
/*基本结构与判断---------------------------------*/
struct Node {//记录当前结点的状态,以及前驱结点
string s;//283104765
int pre;//
Node() {}
Node(string _s, int _pre) : s(_s), pre(_pre) {}
};
vector<Node>v;//Node v[100000]
int dis[5] = { -1,1,-3,3 };//四个方向,上下左右
bool Judge(int pos, int i) { //是否符合要求,要转换二维分析
/*处在最左边不能左移,最右边不能右移*/
/*280314765*/
if (pos % 3 == 0 && i == 0 || pos % 3 == 2 && i == 1) return false;
return pos + dis[i] > -1 && pos + dis[i] < 9;//[0,8]
}
/*-----------------------------------------------*/
/*输入输出*/
void Out(string s) {
for (int i = 0;i < 3;++i) {
cout << " - - -\n|";
for (int j = i * 3;j < 3 * i + 3;++j) cout << s[j] << "|";
cout << endl;
}
cout << endl;
}
void Print(Node ans) {
if (ans.pre != -1) Print(v[ans.pre]);
Out(ans.s);
return;
}
/*-----------------------------------------------*/
/*暴力广搜---------------------------------------*/
void Bfs() {
/*这题类似于迷宫求解,保存路径。因此采用模拟队列的方法*/
int front = 0, tail = 1;
string tmp;
unordered_map<string, bool>mp;
v.push_back(Node(s0, -1));//将初始状态放入队列
mp[s0] = 1;//每个节点只能拓展一次
while (front < tail) {//队列全部找过
if (v[front].s.compare(sg) == 0) {//123456780 123456780
cout << "I got it!" << endl;
Print(v[front]);
return;
}
int pos = v[front].s.find("0");//找到空格的位置 s0 s1 s2 s3 s4 s5
for (int i = 0;i < 4;++i) {
if (Judge(pos, i)) {
tmp = v[front].s;//283104765->283014765
swap(tmp[pos], tmp[pos + dis[i]]);//
if (mp[tmp] == 0) {
v.push_back(Node(tmp, front));//open
mp[tmp] = 1;
tail++;//v[1]=tmp,v[tail2]
}
}
}
front++;
}
}
int main() {
double s, e;
/*freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);*/
while(1) {
cin >> s0;
cin >> sg;
if (Is_odd(s0) == Is_odd(sg)) Bfs();
else cout << "No solution!" << endl;
}
return 0;
}