六数码问题
问题描述:
代码:
#include <iostream>
#include<vector>
#include<queue>
#include<math.h>
using namespace std;
queue<int>Q;//定义全局变量Q,遍历过程中的叶子数,和最后计算出的次数。
int yezi=0;
int cishu=0;
//阿尔法变换,参数为一个六位数整数,最后返回一个变换一次后的整数。
int aerfa(int temp){
int part[6];
for(int i=5;i>=0;i--){
part[i]=temp%10;
temp=temp/10;
}
int t=part[3];
part[3]=part[4];
part[4]=part[1];
part[1]=part[0];
part[0]=t;
int result=0;
for(int i=0;i<6;i++){
result=result*10+part[i];
}
return result;
}
//贝塔变换,参数为一个六位数整数,最后返回一个变换一次后的整数。
int beta(int temp){
int part[6];
for(int i=5;i>=0;i--){
part[i]=temp%10;
temp=temp/10;
}
int t=part[4];
part[4]=part[5];
part[5]=part[2];
part[2]=part[1];
part[1]=t;
int result=0;
for(int i=0;i<6;i++){
result=result*10+part[i];
}
return result;
}
/*
广搜,类似于层次遍历,首先将Q队列的队头出队,记录出队的队头元素为q,每出队
一个元素,叶子数就加1,如果q等于123456,则返回1,退出bfs()。如果q不等于
123456,则对其分别进行一次阿尔法变换和一次贝塔变换。变换之后的整数都进队
(类似于层次遍历),然后循环这个过程,出队--->判断--->分别进行阿尔法变化
和贝塔变化--->再分别进队。最后如果能变换到123456,则返回1,否则返回0.
*/
int bfs(){
while(!Q.empty())
{
int q=Q.front();
Q.pop();
yezi++;
if(q==123456){
// cout<<"叶子为"<<yezi<<endl;
return 1;
}
for(int i=0;i<2;i++){
if(i==0){
int bf=aerfa(q);
Q.push(bf);
}
else{
int bf2=beta(q);
Q.push(bf2);
}
}
}
//cout<<"叶子为"<<yezi<<endl;
return 0;
}
/*
主函数中,先让用户输入n,用一个大循环控制n,每次让用户输入六个数,并将这六个数转变为整数的形式,将其扔到Q中,然后就执行bfs()函数,最后判断返回的结果,如果返回1,叶子所在高度=log以2为底的叶子数,计算出叶子所在高度,这里的高度实际上就是变换的次数,一次大循环之后,要将叶子数清零,次数清零,Q队列清空,然后进行第二次大循环。
*/
int main()
{int n;
cin>>n;
vector<int>final;//存放最后结果
for(int i=0;i<n;i++){
int oringin[6];
for(int j=0;j<6;j++){
cin>>oringin[j];
}
//将六个数结合成一个整数
int start=0;
for(int k=0;k<6;k++){
start=start*10+oringin[k];
}
Q.push(start);
if(bfs()==1){
cishu=(int)(log(yezi)/log(2));
final.push_back(cishu);
}
else{
final.push_back(-1);
}
cishu=0;
while(!Q.empty()){
Q.pop();
; }
yezi=0;
}
for(vector<int>::iterator it=final.begin();it!=final.end();it++){
cout<<*it<<endl;
}
return 0;
}