#include<bits/stdc++.h>
using namespace std;
int num[6][6];
map<int,int>m;
struct node{
int num;
int step;
};
void build(int temp){
memset(num,0,sizeof(num));
for(int i=3;i>=1;i--){
for(int j=3;j>=1;j--){
num[i][j]=temp%10;
temp/=10;
}
}
}
int change(int k){
int n,dir;
if(k<=6){//k<6让行改变
n=(k+1)/2;dir=(k%2);
if(dir==1){
num[n][0]=num[n][3];
for(int i=3;i>=1;i--)num[n][i]=num[n][i-1];
}
else{
num[n][4]=num[n][1];
for(int i=1;i<=3;i++)num[n][i]=num[n][i+1];
}
}
if(k>6){//k>6让列改变
n=(k+1-6)/2;dir=(k%2);
if(dir==1){
num[0][n]=num[3][n];
for(int i=3;i>=1;i--)num[i][n]=num[i-1][n];
}
else{
num[4][n]=num[1][n];
for(int i=1;i<=3;i++)num[i][n]=num[i+1][n];
}
}
int temp=0;
for(int i=1;i<=3;i++)for(int j=1;j<=3;j++)temp=temp*10+num[i][j];//从新把密码矩阵压缩成数字并返回回去
return temp;
}
void bfs(int temp){
queue<node>q;
while(!q.empty())q.pop();
node t;
t.num=temp;t.step=0;
q.push(t);
while(!q.empty()){
node now=q.front();
q.pop();
for(int i=1;i<=12;i++){//判断12个方向
node next;
build(now.num);
next.num=change(i);
next.step=now.step+1;
if(!m.count(next.num) && next.step<=5){//如果next.num没有在映射里面出现过,并且还可以继续搜就继续
m[next.num]=now.step+1;
q.push(next);
}
}
}
}
int main(){
int test;
scanf("%d",&test);
while(test--){
m.clear();//清空映射 (有兴趣可自行百度映射怎么用)
int ok=0;
int temp=0;
scanf("%d",&temp);
build(temp);//把数字还原到密码矩阵里
m[temp]=0;
if(m.count(123456789)){//判断数字123456789是否在映射里出现过
printf("0\n");
continue;
}
else bfs(temp);//广搜
if(m.count(123456789))printf("%d\n",m[123456789]);
else printf("impossible\n");
}
}
月赛最后一题答案
最新推荐文章于 2019-05-27 17:10:47 发布