给你一个3x3的魔方,假设初始状态如下,再给你一个目标状态,问最少几步操作能到达目标状态?
123
456
789
操作方法如下:首先有四块小魔方如下,
12 23 45 56
45 56 78 89
现在告诉你有三种旋转方式,顺时针90度,180度,270度
例如对魔方1(初始状态在最上面)旋转90度,180分别会变成
413 543
526 216
789 789
#include<string>
#include<deque>
#pragma warning(disable:4786)
#include<map>
#include<iostream>
using namespace std;
struct MyState
{
string state;
int step;
};
int Index[4][4]={{0,1,3,4},{1,2,4,5},{3,4,6,7},{4,5,7,8}};//魔方1下标为{0,1,3,4}
deque<MyState> deq;
map<string,int> m;
void rotation_op(string &str,int n){//第n个小魔方,第一个魔方0134旋转90°变3041
char first_index=str[Index[n][0]];
str[Index[n][0]]=str[Index[n][2]];
str[Index[n][2]]=str[Index[n][3]];
str[Index[n][3]]=str[Index[n][1]];
str[Index[n][1]]=first_index;
}
int BFS(string &str,const string &G){
if(!str.compare(G))
return 0;//一开始的状态就是目标状态
MyState tempstate;
tempstate.state=str;
tempstate.step=0;
deq.push_back(tempstate);//旋转90,180,270的压入队列
m[str]=1;
while(!deq.empty()){
string cur = deq.front().state;
int step = deq.front().step;
deq.pop_front();
for(int index=0;index<4;index++){
for(int type=0;type<4;type++){//3种旋转类型,最后一种是为了回溯还原状态
rotation_op(cur,index);//旋转90
if(m.find(cur)==m.end()){//没访问过
if(!cur.compare(G))
return step+1;//找到答案,返回步数
MyState tempstate;
tempstate.state=cur;
tempstate.step=step+1;
deq.push_back(tempstate);
m[cur]=1;
}
}
}
}
}
int main(){
int T,t;
cin>>T;
while(T--){
m.clear();
deq.clear();
string orgin="";
string goal="";
for(int i=0;i<18;i++){ //9(原始状态)+9(目标状态 )
cin>>t;
if(i<9)
orgin+=(t+'0');
else
goal+=(t+'0');
}
cout<<BFS(orgin,goal)<<endl;
}
return 0;
}
/*
2
1 2 3
4 5 6
7 8 9
5 4 1
6 2 3
7 8 9
1 2 3
4 5 6
7 8 9
2 5 3
1 4 6
7 8 9
3
1
*/