Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // B
- //time:444.431s
- //memory: 380.00Kb
- #define DONE 1147797409030816545
- #include <sstream>
- #include <iostream>
- #include <queue>
- using namespace std;
- const unsigned long long Masks[] = {
- 0x000000000000000F,
- 0x00000000000000F0,
- 0x0000000000000F00,
- 0x000000000000F000,
- 0x00000000000F0000,
- 0x0000000000F00000,
- 0x000000000F000000,
- 0x00000000F0000000,
- 0x0000000F00000000,
- 0x000000F000000000,
- 0x00000F0000000000,
- 0x0000F00000000000,
- 0x000F000000000000,
- 0x00F0000000000000,
- 0x0F00000000000000,
- 0xF000000000000000,
- };
- const unsigned long long AntiMasks[] = {
- 0xFFFFFFFFFFFFFFF0,
- 0xFFFFFFFFFFFFFF0F,
- 0xFFFFFFFFFFFFF0FF,
- 0xFFFFFFFFFFFF0FFF,
- 0xFFFFFFFFFFF0FFFF,
- 0xFFFFFFFFFF0FFFFF,
- 0xFFFFFFFFF0FFFFFF,
- 0xFFFFFFFF0FFFFFFF,
- 0xFFFFFFF0FFFFFFFF,
- 0xFFFFFF0FFFFFFFFF,
- 0xFFFFF0FFFFFFFFFF,
- 0xFFFF0FFFFFFFFFFF,
- 0xFFF0FFFFFFFFFFFF,
- 0xFF0FFFFFFFFFFFFF,
- 0xF0FFFFFFFFFFFFFF,
- 0x0FFFFFFFFFFFFFFF
- };
- struct Element{
- unsigned long long data; // sequence
- string Prev; // Prev;
- unsigned long long Dist;
- unsigned long long Father;
- Element(string P): Prev(P), Dist(0), Father(0) {}
- void setAt( int place, unsigned char value )
- {
- data = ( data & AntiMasks[place] ) | ( static_cast<long long>( value ) << ( place << 2 ) );
- }
- unsigned char getAt( int place ) const
- {
- return static_cast<unsigned char>( ( data & Masks[place] ) >> ( place << 2 ) );
- }
- unsigned long long H(){
- unsigned long long h = 0;
- for(int i = 0; i<16; i++){
- char value = getAt(i);
- if(value != 0){
- int targetX = (value - 1) / 4; // expected x-coordinate (row)
- int targetY = (value - 1) % 4; // expected y-coordinate (col)
- int dx = i/4 - targetX; // x-distance to expected coordinate
- int dy = i%4 - targetY; // y-distance to expected coordinate
- h += (abs(dx) + abs(dy));
- }
- }
- return h;
- }
- void F(){
- Dist = Prev.size()+H();
- }
- };
- Element MoveRight(Element l, int pos){
- l.Father = l.data;
- unsigned char k = l.getAt(pos+1);
- l.setAt(pos,k);
- l.setAt(pos+1,0);
- l.Prev = l.Prev +'L';
- l.F();
- return l;
- }
- Element MoveLeft(Element l, int pos){
- l.Father = l.data;
- unsigned char k = l.getAt(pos-1);
- l.setAt(pos, k);
- l.setAt(pos-1,0);
- l.Prev = l.Prev +'R';
- l.F();
- return l;
- }
- Element MoveUp(Element l, int pos){
- l.Father = l.data;
- unsigned char k = l.getAt(pos-4);
- l.setAt(pos, k);
- l.setAt(pos-4,0);
- l.Prev = l.Prev +'D';
- l.F();
- return l;
- }
- Element MoveDown(Element l, int pos){
- l.Father = l.data;
- unsigned char k = l.getAt(pos+4);
- l.setAt(pos,k);
- l.setAt(pos+4,0);
- l.Prev = l.Prev +'U';
- l.F();
- return l;
- }
- vector<Element> getNodes(Element tmp){
- vector<Element> ToReturn;
- if(tmp.getAt(0) == 0){
- Element toPush = MoveRight(tmp,0);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveDown(tmp,0);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- else if(tmp.getAt(1) == 0){
- Element toPush = MoveRight(tmp,1);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveDown(tmp,1);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveLeft(tmp,1);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- else if(tmp.getAt(2) == 0){
- Element toPush = MoveRight(tmp,2);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveDown(tmp,2);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveLeft(tmp,2);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- else if(tmp.getAt(3) == 0){
- Element toPush = MoveLeft(tmp,3);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveDown(tmp,3);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- else if(tmp.getAt(4) == 0){
- Element toPush = MoveRight(tmp,4);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveDown(tmp,4);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveUp(tmp,4);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- else if(tmp.getAt(5) == 0){
- Element toPush = MoveRight(tmp,5);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveLeft(tmp,5);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveDown(tmp,5);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveUp(tmp,5);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- else if(tmp.getAt(6) == 0){
- Element toPush = MoveRight(tmp,6);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveLeft(tmp,6);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveDown(tmp,6);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveUp(tmp,6);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- else if(tmp.getAt(7) == 0){
- Element toPush = MoveLeft(tmp,7);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveDown(tmp,7);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveUp(tmp,7);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- else if(tmp.getAt(8) == 0){
- Element toPush = MoveRight(tmp,8);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveDown(tmp,8);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveUp(tmp,8);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- else if(tmp.getAt(9) == 0){
- Element toPush = MoveRight(tmp,9);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveLeft(tmp,9);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveDown(tmp,9);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveUp(tmp,9);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- else if(tmp.getAt(10) == 0){
- Element toPush = MoveRight(tmp,10);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveLeft(tmp,10);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveDown(tmp,10);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveUp(tmp,10);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- else if(tmp.getAt(11) == 0){
- Element toPush = MoveLeft(tmp,11);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveDown(tmp,11);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveUp(tmp,11);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- else if(tmp.getAt(12) == 0){
- Element toPush = MoveRight(tmp,12);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveUp(tmp,12);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- else if(tmp.getAt(13) == 0){
- Element toPush = MoveRight(tmp,13);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveLeft(tmp,13);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveUp(tmp,13);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- else if(tmp.getAt(14) == 0){
- Element toPush = MoveRight(tmp,14);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveLeft(tmp,14);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveUp(tmp,14);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- else if(tmp.getAt(15) == 0){
- Element toPush = MoveLeft(tmp,15);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- toPush = MoveUp(tmp,15);
- if(tmp.Father != toPush.data){
- ToReturn.push_back(toPush);
- }
- }
- return ToReturn;
- }
- Element Search(Element node,unsigned long long bound){
- if(node.Dist > bound){
- return node;
- }
- if(node.data == DONE) {
- return node;
- }
- Element min("");
- min.Dist = 100000000;
- vector<Element> vert = getNodes(node);
- for(int i = 0; i < vert.size();i++){
- Element tmp = Search(vert[i], bound);
- if(tmp.data == DONE){
- return tmp;
- }
- if(tmp.Dist < min.Dist){
- min = tmp;
- }
- }
- return min;
- }
- int main(){
- Element start("");
- int ZeroPos = 0;
- for(int i = 0;i < 16;i++){
- int Input;
- cin >> Input;
- start.setAt(i, Input);
- if(Input == 0){
- ZeroPos = i/4;
- }
- }
- int mistakes = ZeroPos+1; //Переменная для подсчета счетности
- for(int i = 0;i < 16;i++){
- for(int j = i+1;j<16;j++){
- int f1 = i/4;
- int f2 = i%4;
- int s1 = j/4;
- int s2 = j%4;
- int first = start.getAt(f1*4+f2);
- int second = start.getAt(s1*4+s2);
- if(first!= 0 && second != 0){
- if(first>second){
- mistakes++;
- }
- }
- }
- }
- if(mistakes%2 !=0){
- cout << "-1";
- return 0;
- }
- // ^ Проверели решаются ли пятнашки
- start.F();
- unsigned long long bound = start.Dist;
- while(1){
- Element tmp = Search(start, bound);
- if(tmp.data == DONE) {
- cout << tmp.Prev.length();
- cout << "\n";
- cout << tmp.Prev;
- return 0;
- }
- bound = tmp.Dist;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement