Untitled
unknown
c_cpp
a year ago
3.8 kB
6
Indexable
#include <iostream>
#include <queue>
#include <cmath>
using namespace std;
#define MAX_MOVE 80
const int goalRow[] = {-1, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3};
const int goalCol[] = {-1, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2};
class State {
public:
int puzzle[4][4];
int heuristic;
int currentMove;
int prevMove;
int ex, ey;
State(int puzzle[4][4]) {
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
this->puzzle[i][j] = puzzle[i][j];
this->ex = -1;
this->ey = -1;
this->currentMove = 0;
this->prevMove = -1;
setHeuristic();
}
State(const State& s) {
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
puzzle[i][j] = s.puzzle[i][j];
currentMove = s.currentMove;
prevMove = s.prevMove;
ex = s.ex;
ey = s.ey;
heuristic = s.heuristic;
}
void setHeuristic() {
int h = 0;
for (int i=0; i<4; i++) {
for (int j=0; j<4; j++) {
if (puzzle[i][j]) {
int goalX = goalRow[puzzle[i][j]];
int goalY = goalCol[puzzle[i][j]];
h += abs(goalX - i) + abs(goalY - j);
if (i == goalX) {
for (int k=j; k<4; k++) {
if (puzzle[i][k] > 0 && goalRow[puzzle[i][k]] == i && puzzle[i][j] > puzzle[i][k]) h += 2;
}
}
if (j == goalY) {
for (int k=i; k<4; k++) {
if (puzzle[k][j] > 0 && goalCol[puzzle[k][j]] == j && puzzle[i][j] > puzzle[k][j]) h += 2;
}
}
}
}
}
this->heuristic = h;
}
void update(int i, int newx, int newy) {
prevMove = i;
swap(puzzle[newx][newy], puzzle[ex][ey]);
ex = newx;
ey = newy;
currentMove++;
setHeuristic();
}
bool operator<(const State& rhs) const {
return currentMove + heuristic > rhs.currentMove + rhs.heuristic;
}
};
int main() {
int puzzle[4][4];
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
cin >> puzzle[i][j];
State s(puzzle);
for (int i=0; i<4; i++) {
for (int j=0; j<4; j++) {
if (!puzzle[i][j]) {
s.ex = i;
s.ey = j;
}
}
}
priority_queue<State> pq;
pq.push(s);
const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, 1, -1};
while (!pq.empty()) {
State curState = pq.top();
if (curState.heuristic == 0) {
cout << curState.currentMove << endl;
break;
}
pq.pop();
if (curState.heuristic + curState.currentMove > MAX_MOVE)
continue;
for (int i=0; i<4; i++) {
int newx = curState.ex + dx[i];
int newy = curState.ey + dy[i];
if (newx < 0 || newy < 0 || newx > 3 || newy > 3)
continue;
if (i == (curState.prevMove ^ 1))
continue;
State nextState = curState;
nextState.update(i, newx, newy);
pq.push(nextState);
}
}
if (pq.empty())
cout << -1 << endl;
return 0;
}Editor is loading...
Leave a Comment