题目:
代码如下:
#include<bits/stdc++.h>
using namespace std;
struct node
{
int a[3][3];
bool operator == (const node &x) const{ //判断是否相等
for(int i = 0;i < 3;i++){
for(int j = 0;j < 3;j++){
if(a[i][j] != x.a[i][j]) return 0;
}
}
return 1;
}
int tonum(){ //将魔方每列拼起来
int res = 0;
for(int i = 0;i < 3;i++)
for(int j = 0;j < 3;j++)
res = res * 10 + a[i][j];
return res;
}
}init;
node rotate(node a,int s,int d)
{
node res = a;
if(d == -1){ //右移
int temp = res.a[s][2];
res.a[s][2] = res.a[s][1];
res.a[s][1] = res.a[s][0];
res.a[s][0] = temp;
}
else if(d == 1){ //左移
int temp = res.a[s][0];
res.a[s][0] = res.a[s][1];
res.a[s][1] = res.a[s][2];
res.a[s][2] = temp;
}
else if(d == -2){ //上移
int temp = res.a[0][s];
res.a[0][s] = res.a[1][s];
res.a[1][s] = res.a[2][s];
res.a[2][s] = temp;
}
else if(d == 2){ //下移
int temp = res.a[2][s];
res.a[2][s] = res.a[1][s];
res.a[1][s] = res.a[0][s];
res.a[0][s] = temp;
}
return res;
}
int bfs(node st)
{
queue<node> q;
map<int,int> d;
q.push(st);
d[st.tonum()] = 0;
while(!q.empty()){
node x = q.front();
q.pop();
int tt = x.tonum();
if(x == init) return d[x.tonum()];
node temp;
for(int i = 0;i < 3;i++){
temp = rotate(x,i,-1);
if(!d.count(temp.tonum())){
d[temp.tonum()] = d[tt] + 1;
q.push(temp);
}
temp = rotate(x,i,1);
if(!d.count(temp.tonum())){
d[temp.tonum()] = d[tt] + 1;
q.push(temp);
}
}
for(int i = 0;i < 3;i++){
temp = rotate(x,i,-2);
if(!d.count(temp.tonum())){
d[temp.tonum()] = d[tt] + 1;
q.push(temp);
}
temp = rotate(x,i,2);
if(!d.count(temp.tonum())){
d[temp.tonum()] = d[tt] + 1;
q.push(temp);
}
}
}
return -1;
}
int main()
{
for(int i = 0;i < 3;i++)
for(int j = 0;j < 3;j++)
init.a[i][j] = i * 3 + j + 1; //初始状况
node t;
for(int i = 0;i < 3;i++){//将每次输入的三位数一个个拆开
int n;
cin >> n;
t.a[i][2] = n % 10;
n /= 10;
t.a[i][1] = n % 10;
n /= 10;
t.a[i][0] = n;
}
int ans = bfs(t);
cout << ans << endl;
return 0;
}
首先需要用结构体来记录原始状态的情况,随后每次输入一个三位数都要把这个数的个位,十位,百位保存下来。每一次旋转如何来对已经出现的情况来判重呢?这里我使用了map,出现一种情况就把魔方的三行拼起来,举个例子,假如刚开始魔方第一行是132,第二行是456,第三行是789.那么此时拼起来就应该是132456789这个数,然后让这个数的map为上一步的步数加一。如果一个9位数的map的值为0就代表没有尝试过这种可能,不然代表之前已经试过了,直接跳过。随后对魔方进行上下左右四种转动的情况进行讨论,接下来的做法就是普通bfs题基本的套路了。