#include #include #include #include class State{ static int trans(int k){ return (k / 10 - 1) * 7 + k % 10; } int table[8][4]; public: int count; State(const int table_[7][4]): count(0){ for(int i = 0; i < 7; i++){ for(int j = 0; j < 4; j++){ if(table_[i][j] % 10 == 1){ table[i + 1][j] = 0; table[0][table_[i][j] / 10 - 1] = trans(table_[i][j]); }else{ table[i + 1][j] = trans(table_[i][j]); } } } if(0){ for(int y = 0; y < 4; y++){ for(int x = 0; x < 8; x++){ std::cout << get(x, y) << ' '; } std::cout << std::endl; } } } int get(int x, int y) const {return table[x][y];} void set_(int x, int y, int s){table[x][y] = s;} bool operator < (const State & s) const { return memcmp(table, s.table, sizeof(table)) < 0; } bool isComplete(){ for(int x = 0; x < 7; x++){ for(int y = 0; y < 4; y++){ if(get(x, y) != x + y * 7 + 1){ return false; } } } return true; } }; void addNewStates(std::list & q, std::set & cache, const State & current){ cache.insert(current); int dict[8 * 4]; for(int y = 0; y < 4; y++){ for(int x = 0; x < 8; x++){ dict[current.get(x, y)] = x * 1000 + y; } } for(int y = 0; y < 4; y++){ for(int x = 0; x < 8; x++){ int prev = current.get(x - 1, y); if(current.get(x, y) != 0 || prev % 7 == 0){ continue; } int x_ = dict[prev + 1] / 1000; int y_ = dict[prev + 1] % 1000; State next = current; next.set_(x_, y_, 0); next.set_(x, y, prev + 1); next.count = current.count + 1; if(cache.find(next) == cache.end()){ cache.insert(next); q.push_back(next); } } } } int f(const int table[7][4]){ State s(table); std::set cache; std::list q; q.push_back(s); int limit = 1; while(!q.empty()){ s = q.front(); q.pop_front(); if(s.isComplete()){return s.count;} addNewStates(q, cache, s); if(cache.size() > limit){ //std::cout << "size = " << cache.size() << std::endl; limit *= 10; } } return -1; } int main(){ int table[7][4]; int Case; std::cin >> Case; while(Case--){ for(int i = 0; i < 4; i++){ for(int j = 0; j < 7; j++){ std::cin >> table[j][i]; } } std::cout << f(table) << std::endl; } }