题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2234
IDA*:每次移动改变四个点的位置,即h()=(最少可能的横向或纵向不在位置上的点的个数+3)/4 )
IDA*:每次移动改变四个点的位置,即h()=(最少可能的横向或纵向不在位置上的点的个数+3)/4 )
#include<cstdio>
#include<cstring>
using namespace std;
char maze[5][5];
inline void roL(int x){
char t=maze[x][0];
maze[x][0]=maze[x][1];
maze[x][1]=maze[x][2];
maze[x][2]=maze[x][3];
maze[x][3]=t;
}
inline void roR(int x){
char t=maze[x][3];
maze[x][3]=maze[x][2];
maze[x][2]=maze[x][1];
maze[x][1]=maze[x][0];
maze[x][0]=t;
}
inline void roU(int x){
char t=maze[0][x];
maze[0][x]=maze[1][x];
maze[1][x]=maze[2][x];
maze[2][x]=maze[3][x];
maze[3][x]=t;
}
inline void roD(int x){
int t=maze[3][x];
maze[3][x]=maze[2][x];
maze[2][x]=maze[1][x];
maze[1][x]=maze[0][x];
maze[0][x]=t;
}
bool flag[5];
inline int h(){
int val=20;
int tmp=0;
for(int i=0;i<4;i++){
int cnt=4;
memset(flag,false,sizeof(flag));
for(int j=0;j<4;j++){
if(flag[maze[i][j]-'1']) continue;
flag[maze[i][j]-'1']=true;
cnt--;
}
tmp+=3-cnt;
}
if(tmp<val) val=tmp;
tmp=0;
for(int i=0;i<4;i++){
int cnt=4;
memset(flag,false,sizeof(flag));
for(int j=0;j<4;j++){
if(flag[maze[j][i]-'1']) continue;
flag[maze[j][i]-'1']=true;
cnt--;
}
tmp+=3-cnt;
}
if(tmp<val) val=tmp;
return val;
}
int deep;
bool dfs(int d){
if(d==deep&&h()==0) return true;
if(d+(h()+3)/4>deep) return false;
for(int i=0;i<4;i++){
roL(i);
if(dfs(d+1)) return true;
roR(i);
roR(i);
if(dfs(d+1)) return true;
roL(i);
roU(i);
if(dfs(d+1)) return true;
roD(i);
roD(i);
if(dfs(d+1)) return true;
roU(i);
}
return false;
}
inline void in(char& c){
c=getchar();
while(c<=32) c=getchar();
}
int main(){
int t;
scanf("%d",&t);
while(t--){
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
in(maze[i][j]);
}
}
deep=0;
while(deep<=5){
if(dfs(0)) break;
deep++;
}
if(deep<=5) printf("%d\n",deep);
else puts("-1");
}
return 0;
}