Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <queue>
- #include <set>
- #include <algorithm>
- #include <map>
- struct State {
- std::vector<int> arr;
- int prev = -1;
- char movement = ' ';
- int number = 0;
- int d = -1;
- State() { arr.resize(16); }
- };
- void move_left(State &s1, State &s2, int curnum) {
- int i;
- for (i = 0; i < 16; ++i) {
- if (s1.arr[i] == 0)
- break;
- }
- for (int j = 0; j < 16; ++j) {
- if (j == i)
- s2.arr[j] = s1.arr[i - 1];
- else if (j == i - 1)
- s2.arr[j] = 0;
- else
- s2.arr[j] = s1.arr[j];
- }
- s2.movement = 'L';
- s2.prev = s1.number;
- s2.number = curnum;
- }
- void move_right(State &s1, State &s2, int curnum) {
- int i;
- for (i = 0; i < 16; ++i) {
- if (s1.arr[i] == 0)
- break;
- }
- for (int j = 0; j < 16; ++j) {
- if (j == i)
- s2.arr[j] = s1.arr[i + 1];
- else if (j == i + 1)
- s2.arr[j] = 0;
- else
- s2.arr[j] = s1.arr[j];
- }
- s2.movement = 'R';
- s2.prev = s1.number;
- s2.number = curnum;
- }
- void move_up(State &s1, State &s2, int curnum) {
- int i;
- for (i = 0; i < 16; ++i) {
- if (s1.arr[i] == 0)
- break;
- }
- for (int j = 0; j < 16; ++j) {
- if (j == i)
- s2.arr[j] = s1.arr[i - 4];
- else if (j == i - 4)
- s2.arr[j] = 0;
- else
- s2.arr[j] = s1.arr[j];
- }
- s2.movement = 'U';
- s2.prev = s1.number;
- s2.number = curnum;
- }
- void move_down(State &s1, State &s2, int curnum) {
- int i;
- for (i = 0; i < 16; ++i) {
- if (s1.arr[i] == 0)
- break;
- }
- for (int j = 0; j < 16; ++j) {
- if (j == i)
- s2.arr[j] = s1.arr[i + 4];
- else if (j == i + 4)
- s2.arr[j] = 0;
- else
- s2.arr[j] = s1.arr[j];
- }
- s2.movement = 'D';
- s2.prev = s1.number;
- s2.number = curnum;
- }
- class Compare {
- public:
- bool operator()(const std::vector<int> &a, const std::vector<int> &b) {
- for (int i = 0; i < 16; ++i)
- if (a[i] < b[i])
- return true;
- else if (a[i] > b[i])
- return false;
- return false;
- }
- };
- bool check_if_right(State &s) {
- for (int i = 0; i < 15; ++i)
- if (s.arr[i] != i + 1)
- return false;
- return true;
- }
- int count_manhattan(State& s){
- int dest = 0;
- for( int i = 0; i < 16; ++i){
- dest += abs(s.arr[i] % 4 - i % 4) + abs(s.arr[i] / 4 - i / 4);
- }
- return dest;
- }
- bool play(State &s0, std::vector<char> &strategy) {
- int curnum = 0;
- std::vector<State> positions;
- std::multimap<int, State> states;
- std::set<std::vector<int>, Compare> used;
- used.insert(s0.arr);
- states.emplace(0, s0);
- positions.push_back(s0);
- s0.number = curnum;
- ++curnum;
- while (!states.empty()) {
- State cur = states.begin()->second;
- if (check_if_right(cur)) {
- int pos = cur.number;
- while (pos != -1) {
- strategy.emplace_back(positions[pos].movement);
- pos = positions[pos].prev;
- }
- std::reverse(strategy.begin(), strategy.end());
- return true;
- }
- int i;
- for (i = 0; i < 16; ++i)
- if (cur.arr[i] == 0)
- break;
- if (i / 4 > 0) {
- State temp;
- move_up(cur, temp, curnum);
- if (used.find(temp.arr) == used.end()) {
- positions.push_back(temp);
- used.insert(temp.arr);
- temp.d = cur.d + 1;
- states.emplace(temp.d + count_manhattan(temp), temp);
- ++curnum;
- }
- }
- if (i / 4 < 3) {
- State temp;
- move_down(cur, temp, curnum);
- if (used.find(temp.arr) == used.end()) {
- positions.push_back(temp);
- used.insert(temp.arr);
- temp.d = cur.d + 1;
- states.emplace(temp.d + count_manhattan(temp), temp);
- ++curnum;
- }
- }
- if (i % 4 > 0) {
- State temp;
- move_left(cur, temp, curnum);
- if (used.find(temp.arr) == used.end()) {
- positions.push_back(temp);
- used.insert(temp.arr);
- temp.d = cur.d + 1;
- states.emplace(temp.d + count_manhattan(temp), temp);
- ++curnum;
- }
- }
- if (i % 4 < 3) {
- State temp;
- move_right(cur, temp, curnum);
- if (used.find(temp.arr) == used.end()) {
- positions.push_back(temp);
- used.insert(temp.arr);
- temp.d = cur.d + 1;
- states.emplace(temp.d + count_manhattan(temp), temp);
- ++curnum;
- }
- }
- states.erase(states.begin());
- }
- return false;
- }
- int main() {
- State s0;
- std::vector<char> strategy;
- int num = 0;
- for (int i = 0; i < 16; ++i) {
- std::cin >> num;
- s0.arr[i] = num;
- }
- bool mark = play(s0, strategy);
- if (mark) {
- std::cout << strategy.size() - 1 << std::endl;
- for (int i = 1; i < strategy.size(); ++i)
- std::cout << strategy[i];
- } else
- std::cout << -1;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement