#include <iostream> using namespace std; int v[25][4]; int n; int s[25][4]; int snum[25]; int c=0; int p[5][5][4] = {0}; int solve(int num) //从左到右,从上到下的放入箱子,num标示放入目标位置的第几个箱子 { if(num == n*n) return 1; //这里剪枝了。剪去了相同箱子的重复处理 for(int i=0; i<c; i++) //只对不同的箱子处理,遍历所有不同的箱子。 { if(snum[i] > 0) //只对箱子数还大于0的处理 { //得到目标位置坐标 int x=num/n; int y=num%n; //p表示每一个小三角形 if(x==0 && y==0) //这是0号位置,什么都不要考虑 { p[x][y][0] = s[i][0]; p[x][y][1] = s[i][1]; p[x][y][2] = s[i][2]; p[x][y][3] = s[i][3]; snum[i]--; //把s中的第i个箱子放入了目标位置 if(solve(num+1) == 1) return 1; snum[i]++; } else { if(x==0)//第一排,只要考虑左边3号位置 { if(s[i][3] == p[x][y-1][1]) { p[x][y][0] = s[i][0]; p[x][y][1] = s[i][1]; p[x][y][2] = s[i][2]; p[x][y][3] = s[i][3]; snum[i]--; if(solve(num+1) == 1) return 1; snum[i]++; } } if(y==0) //第一列,只要考虑上边0号置 { if(s[i][0] == p[x-1][y][2]) { p[x][y][0] = s[i][0]; p[x][y][1] = s[i][1]; p[x][y][2] = s[i][2]; p[x][y][3] = s[i][3]; snum[i]--; if(solve(num+1) == 1) return 1; snum[i]++; } } if(x!=0 && y!=0) //除云第一排,第一列,其它所有位置。只要考虑上边0号位置和左边3号位置 { if(s[i][0] == p[x-1][y][2] && s[i][3] == p[x][y-1][1]) { p[x][y][0] = s[i][0]; p[x][y][1] = s[i][1]; p[x][y][2] = s[i][2]; p[x][y][3] = s[i][3]; snum[i]--; if(solve(num+1) == 1) return 1; snum[i]++; } } } } } return 0; } int main() { int game = 1; while(cin>>n && n) { c = 0; //初始化数据,主要是对相同种类的箱子作处理 for(int i=0; i<n*n; i++) { for(int j=0; j<4; j++) { cin>>v[i][j]; //初始化箱子数据。 n*n个箱子 } int temp = 1; //标示是否有相同的箱子。有则为0,否则为1; for(int k=0; k<c; k++) { if(v[i][0] == s[k][0] && v[i][1] == s[k][1] && v[i][2] == s[k][2] && v[i][3] == s[k][3]) { temp = 0; snum[k]++; } } //s记下了每种不同的箱子的数据,c记下了有多少种不同的箱子,snum记下了每种箱子的数量 if(temp == 1) //没有相同的箱子,加入s中 { s[c][0] = v[i][0]; s[c][1] = v[i][1]; s[c][2] = v[i][2]; s[c][3] = v[i][3]; snum[c]++; //实则就是snum[c] = 1; c++; } } if(game != 1) cout<<endl; if(solve(0) == 1) printf("Game %d: Possible ", game); else printf("Game %d: Impossible ", game); game++; //还原,为下一题作准备 for(int j=0; j<c; j++) snum[j] = 0; } return 1; }