/* 2003/11/10 19:09-20:56 */ #include #include #include using namespace std; class card { public: unsigned char c; card(); card(int suit, int number); int suit(); int number(); }; card::card() { c = 0; } card::card(int suit, int number) { c = 0; c |= number; c |= (suit-1) << 4; } int card::suit() { return (int)(c>>4) + 1; } int card::number() { return (int)(c & 0x0F); } bool operator<(const card &x, const card &y) { return (x.c < y.c); } bool operator>(const card &x, const card &y) { return (x.c > y.c); } bool operator==(const card &x, const card &y) { return (x.c == y.c); } bool operator!=(const card &x, const card &y) { return (x.c != y.c); } class field { public: card m[4][8]; field(); field(const field &_f); }; field::field() { ; } field::field(const field &_f) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 8; j++) { m[i][j] = _f.m[i][j]; } } } bool operator==(const field &x, const field &y) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 8; j++) { if (x.m[i][j] != y.m[i][j]) return false; } } return true; } bool operator!=(const field &x, const field &y) { return !(x==y); } bool operator<(const field &x, const field &y) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 8; j++) { if (x.m[i][j] < y.m[i][j]) return true; if (x.m[i][j] > y.m[i][j]) return false; } } return false; } bool operator>(const field &x, const field &y) { return (x!=y && !(x done, full; field goal; void mkgoal() { for (int i = 0; i < 4; i++) { for (int j = 0; j < 7; j++) { goal.m[i][j] = card(i+1, j+1); } goal.m[i][7] = card(1, 0); } } /* Generate new-level "done" */ bool bfs() { set done2; done2.clear(); for (set::iterator p = done.begin(); p != done.end(); p++) { field f = *p; for (int i = 0; i < 4; i++) { for (int j = 0; j < 8; j++) { if (f.m[i][j].number() == 0) { if (f.m[i][j-1].number() == 7 || f.m[i][j-1].number() == 0) { continue; } bool found = false; for (int y = 0; y < 4; y++) { for (int x = 0; x < 8; x++) { if (f.m[i][j-1].suit() == f.m[y][x].suit() && f.m[i][j-1].number() + 1 == f.m[y][x].number()) { f.m[i][j] = f.m[y][x]; f.m[y][x] = card(1, 0); found = true; break; } } if (found) break; } quit1:; if (found) { if (goal == f) { return true; } if ((full.insert(f)).second) { done2.insert(f); } f = *p; } } } } } done = done2; return false; } void initmove(field &f) { for (int i = 0; i < 4; i++) { f.m[i][0] = card(i+1, 1); } for (int i = 0; i < 4; i++) { for (int j = 1; j <= 7; j++) { if (1 == f.m[i][j].number()) { f.m[i][j] = card(1, 0); } } } } int main() { int nset, iset, c; field f; mkgoal(); cin >> nset; for (iset = 0; iset < nset; iset++) { done.clear(); full.clear(); for (int i = 0; i < 4; i++) { f.m[i][0] = card(1, 0); for (int j = 0; j < 7; j++) { cin >> c; f.m[i][j+1] = card(c/10, c%10); } } initmove(f); done.insert(f); full.insert(f); if (goal == f) { cout << 0 << endl; continue; } for (int i = 1; ; i++) { if (bfs()) { cout << i << endl; break; } if (done.size() == 0) { cout << -1 << endl; break; } } } return 0; }