#include<iostream>
#include<queue>
#include<cmath>
#include<string>
#include<utility>
#include<vector>
#include<time.h>
#include<set>
#include<map>
using namespace std;
class Chessboard;
vector<Chessboard> chessboard;
priority_queue<Chessboard> pr_chessboard;
map<string, bool> cst;
//pair<int, int> chess_vector;//前面棋局的东西
int DIR[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };
int DIRV[4] = {3,-3,1,-1};
class Chessboard {
public:
int pre;
int indx;
string chess;
int h;
int g;
bool operator <(const Chessboard& a)const {
return a.g+a.h < this->g+this->h;
}
Chessboard() :pre(-1),h(0),g(0),indx(0){}
};
//逆序数判断
bool ReverseOrderNumber(string chess) {
int number=0;
for (int i = 0; i < chess.size(); i++) {
if (chess[i] == '0')continue;
for (int j = 0; j < i; j++) {
if (chess[j] > chess[i]&&chess[j]!='0') {
++number;
}
}
}
return number % 2==1 ? false : true;
}
int ChessBoardStat(string chess) {
int number=0;
//string standard = "12345678";
for (int i = 0; i < chess.size(); i++) {
if (chess[i] == '0')continue;
int temp = chess[i] - '0';
int h = i / 3 - (temp - 1) / 3;
int w = (i - i / 3 * 3 + 1)-(temp-(temp-1)/3*3);
number = number+abs(h) + abs(w);
}
return number;
}
int locate(string chess) {
return chess.find("0");
}
bool vaildMove(int h,int w) {
return h < 3 && h >= 0 && w < 3 && w >= 0;
}
void Output(Chessboard end) {
if (end.pre != -1) {
Output(chessboard[end.pre]);
}
cout << "--------------------" << endl;
for (int i = 0; i < 9;i++) {
cout << end.chess[i];
if ((i + 1) % 3 == 0) {
cout << endl;
}
}
}
int main() {
string input;
cout << "输入棋局比如123456780" << endl;
cin >> input;
bool mode = ReverseOrderNumber(input);
if (!mode) {
cout << "该棋局是无法归位123456780" << endl;
}
cst[input] = true;
Chessboard temp;
temp.chess = input;
temp.h = ChessBoardStat(temp.chess);
chessboard.push_back(temp);
pr_chessboard.push(temp);
clock_t t1 = clock();
while (!pr_chessboard.empty() && mode) {
Chessboard pr_temp = pr_chessboard.top();
pr_chessboard.pop();
if (pr_temp.chess == "123456780") {
Output(pr_temp);
break;
}
int zero_locate = locate(pr_temp.chess);
int h = zero_locate /3;
int w = zero_locate - zero_locate / 3 * 3;
for (int i = 0; i < 4; i++) {
int h1 = h + DIR[i][0];
int w1 = w + DIR[i][1];
if (vaildMove(h1, w1)) {
string vaild_ctr = pr_temp.chess;
vaild_ctr[zero_locate] = vaild_ctr[zero_locate + DIRV[i]];
vaild_ctr[zero_locate + DIRV[i]] = '0';
if (cst.find(vaild_ctr) != cst.end()) {
continue;
}
cst[vaild_ctr] = true;
Chessboard DI;
DI.chess = vaild_ctr;
DI.g = pr_temp.g + 1;
DI.h = ChessBoardStat(vaild_ctr);
DI.pre = pr_temp.indx;
chessboard.push_back(DI);
chessboard[chessboard.size() - 1].indx = chessboard.size() - 1;
pr_chessboard.push(chessboard[chessboard.size() - 1]);
}
}
}
cout << (clock() - t1) * 1.0 / CLOCKS_PER_SEC * 1000 << endl;
return 0;
}